56

使用数据库会话令牌系统,我可以让用户使用用户名/密码登录,服务器可以生成一个令牌(例如 uuid)并将其存储在数据库中并将该令牌返回给客户端。来自那里的每个请求都将包含令牌,服务器将查找令牌是否有效以及它属于哪个用户。

使用 JWT,由于服务器上保存的密钥和客户端保存并随每个请求发送的签名令牌的组合,因此无需将任何关于会话/令牌的内容保存到数据库中。

这很好,但除了保存数据库检查每个请求(无论如何都会很快,因为它只是检查哈希表),我不清楚使用 JWT 有什么好处。有熟悉这个的能解释一下吗?让我们忽略 cookie,它特别是如上所述的数据库自定义令牌和我试图比较和理解其好处的 JWT

4

2 回答 2

36

主要区别在于服务器所需的会话存储大小和查找工作:

  • 在服务器端,JWT 将单个密钥存储在内存(或配置文件)中 - 称为密钥。该密钥有两个用途,它可以创建新的加密令牌,它还可以像“打开所有锁”的万能钥匙一样发挥作用,实际上它会验证所有令牌。因此,服务器对身份验证请求的响应速度要快得多,因为您是否有两两百万用户登录并不重要 - 相同数量的记录(一个,该服务器密钥)将用于验证所有客户端请求。

  • 将用户会话存储在数据库中的传统身份验证会在数据库中为每个用户创建一条记录,从而产生多个密钥。因此,如果您有 200 万用户登录,服务器将创建 200 万条记录,并且对于每个客户端请求,服务器需要在数据库中找到相关的会话记录*。

JWT 将其留给客户端来存储和处理整个会话/用户对象。它实际上更有意义,因为每个客户端只处理自己的数据,因此也不会给客户端带来繁重的工作。

至于您在上一段中写的内容,我们在这里保存的不仅仅是 db 调用。JWT 实际上由于其独立和轻量级的特性而更具可扩展性,它不会随着身份验证请求的堆积而失败,并且它允许服务器处理跨设备和服务的身份验证,而无需在服务器端管理会话。

不过,在安全方面,数据库会话可以说占了上风:由于延迟,它们可以更安全,并且在用户注销后也不太容易受到会话劫持的影响。

* db 存储会话方法可以通过有效缓存和仅将会话 id(而不是整个用户对象)存储在快速键/值服务器(如 Redis)中进行优化。也就是说,在大多数情况下,我仍然会选择 JWT 方法而不是 db。

于 2015-06-23T18:12:51.870 回答
1

基于 Json 的令牌(JWT)克服了以下问题:

  1. 移动问题:原生移动应用似乎在处理 cookie 方面存在问题,因此如果我们需要查询远程 API,会话身份验证可能不是最佳解决方案。
  2. CSRF 问题:如果您遵循 cookie 方式,那么您需要有 CSRF 以避免跨站点请求。

但是 JWT 不使用会话,在移动设备上没有问题,它不需要 CSRF,而且它也可以很好地与 CORS 配合使用。如果您没有有效的令牌,您将无能为力。

另外一个,因为此令牌存储在客户端本地存储/会话存储中,因此您也可以将这些令牌传递给其他客户端,但您必须共享用于生成此 JWT 的相同凭证。

于 2014-10-06T12:57:51.567 回答