在身份验证等情况下,使用jwt而不是会话的优势是什么?

它是作为一个独立的方法使用还是在会话中使用?


当前回答

JWT本身并没有使用“会话”的好处。jwt提供了一种在客户端而不是在服务器上维护会话状态的方法。

当人们问这个问题时,通常的意思是“使用jwt比使用服务器端会话有什么好处”。

对于服务器端会话,您要么必须将会话标识符存储在数据库中,要么将其保存在内存中,并确保客户端始终访问相同的服务器。这两种方法都有缺点。在数据库(或其他集中式存储)的情况下,这成为一个瓶颈和需要维护的东西——本质上是每个请求都要执行的额外查询。

使用内存解决方案,您限制了水平扩展,会话将受到网络问题的影响(客户端在Wifi和移动数据之间漫游,服务器重新启动等)。

将会话移动到客户端意味着您消除了对服务器端会话的依赖,但这也带来了一系列挑战。

安全地存储令牌。 安全运输。 JWT会话有时很难失效。 相信客户的主张。

jwt和其他客户端会话机制都存在这些问题。

智威汤逊特别解决了最后一个问题。了解JWT是什么可能会有所帮助:

It is a bit of information. For user sessions, you could include the username and the time when the token expires. But it could conceivably be anything, even the session ID or the user's entire profile (please don't do that though). It has got a secure signature that prevents malicious parties from generating fake tokens (you need access to the server's private key to sign them and you can verify that they were not modified after they were signed). You send them with every request, just like a cookie or Authorization Header would be sent. In fact, they are commonly sent in the HTTP Authorization header but using a cookie is fine too.

令牌被签名,因此服务器可以验证它的来源。我们假设服务器相信自己有安全签名的能力(您应该使用标准库:不要尝试自己做,并适当地保护服务器)。

关于安全传输令牌的问题,答案通常是通过加密通道(通常是httpS)发送它。

关于在客户机中安全地存储令牌,您需要确保坏人无法获得它。这(主要)意味着防止来自坏网站的JS读取令牌并将其发回给他们。使用与缓解其他类型的XSS攻击相同的策略来缓解这一问题。

If you have a need to invalidate JWTs, there are definitely ways this can be achieved. Storing a per-user epoch for only users who have requested to have their "other sessions terminated" is a very efficient method that will probably be good enough. If an application needs per-session invalidation, then a session ID can be maintained in the same way and the "killed tokens" table can still be maintained to be much smaller than the full user table (you only need to retain records newer than the longest allowed token lifetime). So the ability to invalidate the token partially negates the benefit of client-side sessions in that you would have to maintain this session killed state. This will more than likely be a much smaller table than the original session state table, so the lookups are still more efficient though.

使用JWT令牌的另一个好处是,很容易使用每种语言中可用的库来实现它。它也完全脱离了最初的用户身份验证方案——如果迁移到基于指纹的系统,则不需要对会话管理方案进行任何更改。

一个更微妙的好处是:因为JWT可以携带“信息”,客户端可以访问这些信息,所以现在可以开始做一些聪明的事情了。例如,提醒用户他们的会话将在注销前几天到期,并根据令牌中的到期日期为他们提供重新进行身份验证的选项。任何你能想到的。

简而言之:jwt回答了其他会话技术的一些问题和缺点。

“更便宜”的身份验证,因为您可以消除DB往返(或者至少有一个更小的表要查询!),这反过来支持水平可伸缩性。 防篡改客户端声明。

虽然JWTs没有解决安全存储或传输等其他问题,但它没有引入任何新的安全问题。

围绕jwt存在许多负面影响,但如果您实现了与其他类型的身份验证相同的安全性,就不会有问题。

最后一点:这也不是cookie vs .令牌。cookie是一种存储和传输信息位的机制,也可以用于存储和传输JWT令牌。

其他回答

我有一个类似的问题,在JWT和令牌+缓存之间选择用户身份验证。

读完这些文章后,我很清楚智威汤逊承诺的好处并没有超过它带来的问题。所以令牌+缓存(Redis/Memcached)是我的选择。

认证头vs JWT vs会话——如何为api选择正确的认证技术

api的身份验证技术

停止在会话中使用jwt

我的两美分,这在某种程度上与joepie91著名的博客文章形成了对比。

考虑到今天(和未来)的应用程序(大部分)是云原生的 无状态JWT身份验证有经济上的好处, 随着应用程序的扩展而扩展: 云应用每时每刻都在增加成本。 当用户不再需要“根据”会话存储进行身份验证时,此成本就会降低。 以下是一些不使用JWT会增加应用程序成本的因素:

数据库服务器 全天候运营会话商店需要花钱。 在K8S世界中,您不能使用基于本地存储/内存的解决方案,因为pod是短暂的。 出于同样的原因,棘手的会议也不会有好结果。

存储 存储数据需要花钱。在SSD中存储数据的成本更高。 会话相关的操作需要快速解析,因此光盘驱动器不是一个选择。

I / O 一些云提供商对与光盘相关的I/O收费。

下载 大约在2022年,可以安全地假设API和会话存储是独立的服务器实例。 一些云提供商对从一个实例下载信息到另一个实例收取费用。

扩展会话存储 这会影响到前面提到的所有因素。

如果您使用的是AWS,那么另一个略有不同的视角可能会有用。

我们实现了PHP5。在AWS ElastiCache上集中会话存储在多台服务器上。

在我们转到PHP7之前,它工作得很完美。PHP7很难配置,我们被间歇性的问题所困扰,对于特定的用户来说,会话似乎“失败/不匹配/有点混乱”,然后他们无法登录该设备,直到旧的会话过期。

我们转移到使用DynamoDb来存储会话,没有更多的问题。它稍微慢一些,但只在登录(会话存储)阶段可以注意到。

与此同时,我们实现了AWS cognito来取代我们的身份验证,并开始使用API-Gateway通过lambda python函数来交付内容。

我们使用PHP SDK对Cognito进行身份验证,然后将JWT存储在cookie中,但仍然使用PHP会话来保持我们的遗留代码正常工作。

现在我们有了两个栈,这是两个世界中最好的:PHP7做到了它的位,并将主要内容(非常快)传递给用户。然后JS接管并使用JWT提供额外的内容。

我认为JWT的伟大之处在于,它可以在这两个栈之间传递,并在两种情况下用于对用户进行身份验证。

现在我们想知道是否值得冒险,完全切换到新的JWT系统?

在PHP中,我们仍然使用我们的遗留会话,但我们也将令牌传递给cognito以验证它。这是一点额外的安全,可能是不必要的,但它给人一种温暖舒适的感觉。此外,dynamoDb还可以节省成本和维护费用。

在会话身份验证(或有状态身份验证)中,可以存储比令牌更多的数据。但是您必须将会话对象存储在某个地方,这使得身份验证集中起来。此外,您需要有额外的内存来存储会话,这将增加管理内存的额外工作。如果您的应用程序增长,现在您必须根据需要实现不同的设计,实现会话缓存服务,并将会话存储在web应用程序或数据库中。

在Jwt或一般的无状态身份验证中,您不存储任何东西。将令牌与请求标头一起发送。这使得它成为分散的身份验证。这种身份验证的缺点是令牌撤销。每个代币都有一个到期时间,如果您的代币被盗,它将一直有效直到到期。你必须实现最小化风险的逻辑。

简单的答案是:没有。

一个较长的版本是:

在阅读了GraphQL文档中的建议后,我实现了会话管理的jwt:

如果您不熟悉任何这些身份验证机制,我们 推荐使用express-jwt,因为它很简单,没有牺牲 未来的灵活性。

实现确实很简单,因为它只增加了一点点复杂性。然而,过了一段时间,我(和你一样)开始想知道它的好处是什么。事实证明,就会话管理而言,JWT很少(或者可能没有),正如这篇博客文章详细解释的那样:

停止在会话中使用JWT