不要把 JWT 用做 session

如今不少人使用 JWT 用做 session 管理,这是个糟糕的作法,下面阐述缘由,有不一样意见的同窗欢迎讨论。redis

首先说明一下,JWT 有两种:算法

  • 无状态的 JWT,token 中包含 session 数据。
  • 有状态的 JWT,token 中仅有 session ID,session 数据仍是存储在服务端。

本文讨论的是 “无状态的 JWT”,就是把用户的 session 数据放到 token 中。安全

JWT 不适合作为 session 机制,这么作是有危险的。服务器

不少人喜欢比较 “cookies vs. JWT”,这种比较是无心义的,就像比较苹果和桔子,cookies 是一个存储机制,而 JWT 是加密签名的 token,他们不是对立的,能够一块儿使用,或者独立使用。cookie

正确的比较是“sessions vs. JWT” 和 “cookies vs. Local Storage”。网络

JWT 宣称的优势

人们一般会说 JWT 有以下的好处:session

  • 易于水平扩展
  • 简单易用
  • 加密,更安全
  • 内置过时功能
  • 能够防御 CSRF 攻击
  • 在用户阻止了cookies后还能够工做

对于这些所谓的好处咱们会一一剖析。并发

(1)易于水平扩展负载均衡

把 session 数据放入 JWT,服务端不须要保存 session 信息,那么服务端天然是无状态的,能够随意扩展。高并发

看上去的确带来了扩展上的便利,但实际上没啥优点,服务器端保存 session 没有任何难度:

  • 多服务器场景:能够用专门的 redis 服务器保存 session。
  • 多集群场景:多集群间不须要共享 session,同一个用户始终分配到同一个集群便可。

这都是很成熟的解决方案,没有必要在客户端 token 中保存 session。

(2)简单易用

看似一个小小的 token 比较简单,实则否则,你须要本身去处理 session 的管理,怎么可能比开箱即用的 cookies 更简单。

(3)更安全

由于 JWT 是加密的,不少人认为其更加安全,cookies 没加密,不安全。

其实 cookies 只是存储机制,你彻底可使用加密签名的方式。

还有人认为 cookies 没加密会被拦截读取。

cookies 只是 HTTP 头信息,不负责安全,这个问题应该使用 TLS 来解决,不然,即便 JWT 也无法保证信息的安全。

(4)内置过时功能

这个功能更是没用,是否过时应该由服务端控制,不该交给客户端控制,不然,若是 token 被盗取,服务端将没有任何办法。

(5)能够防御 CSRF 攻击

简单说一下什么是 CSRF 攻击。

打个比方,你登陆了网银,这时已经具有给其余帐户转帐的条件了,好比转帐的接口地址是:

http://xbank.com/transfer?to=123&money=1000

在你没有退出网银以前,你访问了一个恶意网站,其中有一段代码:

<img src=http://xbank.com/transfer?to=456789&money=1000>

这样你就丢钱了。

这只是个朴实的例子,实际状况比这复杂得多,但归根结底,CSRF 攻击就是源于:隐式身份验证机制,就是 cookies 是自动发送给服务端的,没法保证该请求是用户批准的。

因此,不少人就认为使用 JWT 就没这个问题了,由于不用 cookies 了。

那么请问,你是把 JWT 保存在哪里的?有2个保存方式:

  • cookie:这样一样会面临 CSRF 攻击。
  • 其余地方,例如 Local Storage:这样的确避免了 CSRF,但暴露了更严重的安全问题,Local Storage 这类的本地存储是能够被 JS 直接读取的。

其实,防御 CSRF 攻击的正确方式只有:CSRF token。

(6)在用户阻止了cookies后还能够工做

不幸的是,在用户阻止了 cookies 的场景中,一般不只仅是阻止 cookies,而是阻止全部的本地存储,包括 Local Storage。

这样的话,JWT 也一样没法工做。

JWT 的缺点

(1)体积大

若是把 session 信息编码后放入 token,那么其体积会很大,颇有可能超出 cookie 的大小限制,那就只能把 JWT 保存在 Local Storage 了,也就产生了安全问题。

并且,体积大,网络压力就大了。

(2)不安全

这个问题上面分析过了,若是放在 cookie 里,那和传统的 session 方案就差很少了,若是放在别的地方,就有其余安全问题了。

(3)没法使某个 JWT 无效

不像 session,在服务端可使其失效,而 JWT 直到其过时才能无效。

好比服务端检测到了一个安全威胁,也没法使相关的 JWT 失效。

也就是说,当你发现风险时,没法杀死某个 session,若是你想解决这个问题,就须要服务端能够对 session 进行管理,那么就变回有状态的模式了。

(4)session 数据旧了

session 数据是保存在 JWT 中的,其中会有用户的相关信息,例如角色。

在 JWT 过时以前,用户的角色发生了变化,那么这时 JWT 中的信息就是旧的了,由于没法更新。

小结

JWT 真的不适合当作 session 使用,JWT 更适合一次性的命令认证,设置一个很短的有效期。

本文的目的不是说 JWT 很差,而是想说把 JWT 用做 session 是用错了地方。

你是怎么使用 JWT 的?欢迎交流讨论。

翻译整理自:
http://cryto.net/~joepie91/bl...

推荐阅读:

相关文章
相关标签/搜索