JWT 和 Session 对比

由于 HTTP 协议是无状态协议,所以 HTTP 协议本身是无法区别身份的。

传统上,一般通过 Session 配合 Cookie 机制解决身份识别问题。

但是在高并发、高流量的服务集群化时,Session 机制遇到极大挑战。而 JWT 认证机制就可以完美的解决这些问题。

 

1. 传统的 Session 认证

我们知道,HTTP 协议本身是一种无状态的协议,而这就意味着如果用户向我们的应用提供了用户名和密码来进行用户认证,那么下一次请求时,用户还要再一次进行用户认证才行,因为根据 HTTP 协议,我们并不能知道是哪个用户发出的请求,所以为了让我们的应用能识别是哪个用户发出的请求,我们只能在服务器存储一份用户登录的信息,这份登录信息会在响应时传递给浏览器,告诉其保存为 cookie,以便下次请求时发送给我们的应用,这样我们的应用就能识别请求来自哪个用户了,这就是传统的基于 session 认证。

但是这种基于 session 的认证使应用本身很难得到扩展,随着不同客户端用户的增加,独立的服务器已无法承载更多的用户,而这时候基于 session 认证应用的问题就会暴露出来。

基于 session 认证所显露的问题:

  • 存储开销
    每个用户经过我们的应用认证之后,我们的应用都要在服务端做一次记录,以方便用户下次请求的鉴别,通常而言session都是保存在内存中,而随着认证用户的增多,服务端的开销会明显增大。
  • 扩展性
    用户认证之后,服务端做认证记录,如果认证的记录被保存在内存中的话,这意味着用户下次请求还必须要请求在这台服务器上,这样才能拿到授权的资源,这样在分布式的应用上,相应的限制了负载均衡器的能力。这也意味着限制了应用的扩展能力。
  • CSRF
    因为是基于 cookie 来进行用户识别的, cookie 如果被截获,用户就会很容易受到跨站请求伪造的攻击。

 

2. 基于 token 的鉴权机制

基于 token 的鉴权机制类似于 HTTP 协议也是无状态的,它不需要在服务端去保留用户的认证信息或者会话信息。这就意味着基于 token 认证机制的应用不需要去考虑用户在哪一台服务器登录了,这就为应用的扩展提供了便利。

基于 token 的鉴权机制流程如下:

  • 用户使用用户名密码来请求服务器;
  • 服务器进行验证用户的信息;
  • 服务器通过验证发送给用户一个token;
  • 客户端存储token,并在每次请求时附送上这个token值;
  • 服务端验证token值,并返回数据;

这个 token 必须要在每次请求时传递给服务端,它应该保存在请求头里, 另外,服务端要支持CORS(跨来源资源共享)策略,一般我们在服务端这么做就可以了Access-Control-Allow-Origin: *。

 

3. JWT 方式

JWT,即 JSON Web Token,它是一种 token 的鉴权机制。

JWT 是一个开放的行业标准(RFC 7519),它定义了一种紧凑的、自包含的方式,通过 JSON 对象在网络应用环境间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。JWT 的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的业务逻辑所须的声明信息。

JWT 最常用于代替 Session,用于识别用户身份。使用 Session 区别用户身份有两个缺点:一是占用服务器存储资源,二是在集群部署下设计非常复杂。JWT 完全可以解决 Session 方案存在的问题。

 

4. JWT 总结

JWT 和 Session 相同点是,它们都是存储用户信息;然而,Session 是在服务器端的,而 JWT 是在客户端的。

Session 方式存储用户信息的最大问题在于要占用大量服务器内存,增加服务器的开销。

而 JWT 方式将用户状态分散到了客户端中,可以明显减轻服务端的内存压力。

Session 的状态是存储在服务器端,客户端只有 session id;而 Token 的状态是存储在客户端。