JWT在身份验证等情况下使用会话的优势是什么?
是用作独立方法还是在会话中使用?
答案 0 :(得分:124)
JWT没有使用"会话"按照说。 JWT提供了一种在客户端上维护会话状态的方法,而不是在服务器上进行。
人们在提出这个问题时通常的意思是"使用JWT比使用服务器端会话"
有什么好处?使用服务器端会话,您必须将会话标识符存储在数据库中,或者将其保留在内存中,并确保客户端始终访问同一服务器。这两者都有缺点。在数据库(或其他集中存储)的情况下,这成为瓶颈和维护的事情 - 实质上是对每个请求进行额外的查询。
使用内存中的解决方案,您可以限制水平扩展,会话将受到网络问题的影响(客户端在Wifi和移动数据之间漫游,服务器重新启动等)
将会话移动到客户端意味着您删除了对服务器端会话的依赖性,但它会带来一系列挑战。
- 安全存储令牌
- 安全运输
- JWT会话有时很难无效
- 信任客户的索赔。
这些问题由JWT和其他客户端会话机制共享。
JWT特别解决了最后一个问题。它可能有助于理解JWT是什么:
这是一些信息。对于用户会话,您可以包括用户名和令牌过期的时间。但它可以想象成任何东西,甚至会话ID或用户的整个配置文件。 (请不要这样做)
它有一个安全的签名,可防止恶意方生成假令牌(您需要访问服务器的私钥才能签名,并且您可以验证它们在签名后未被修改)
你发送每个请求,就像一个cookie或Authorization
标题将被发送。事实上,它们通常在HTTP Authorization
标头中发送,但使用cookie也很好。
令牌已签名,因此服务器可以验证其来源。我们假设服务器信任其自己安全签名的能力(您应该使用标准库:不要尝试自己做,并正确保护服务器)
关于安全传输令牌的问题,答案通常是通过加密频道发送,通常是httpS。
关于将令牌安全地存储在客户端中,您需要确保坏人无法访问它。这(主要)意味着阻止不良网站的JS读取令牌以将其发送回给他们。使用用于缓解其他类型的XSS攻击的相同策略可以减轻这种情况。
如果您需要使JWT无效,肯定有可能实现这一目标。仅为已请求让其他会话终止的用户存储每用户时代"是一种非常有效的方法,可能足够好。如果应用程序需要按会话失效,则可以以相同的方式维护会话ID并且"杀死令牌" table仍然可以保持比完整用户表小得多(你只需要保留比最长允许令牌生命周期更新的记录。)因此,使令牌无效的能力部分地否定了客户端会话的好处,你会必须维持这个会话被杀的状态。这可能是比原始会话状态表小得多的表,因此查找仍然更有效。
使用JWT令牌的另一个好处是,使用可能使用的每种语言的库都可以相当容易地实现它。它也完全脱离了您的初始用户身份验证方案 - 如果您转移到基于指纹的系统,则无需对会话管理方案进行任何更改。
更微妙的好处:因为JWT可以携带"信息"这可以由客户端访问,你现在可以开始做一些聪明的事情。例如,提醒用户他们的会话将在注销前几天到期,根据令牌中的到期日期为他们提供重新进行身份验证的选项。无论你能想象什么。
简而言之:JWT回答了其他会话技巧的一些问题和缺点
1."便宜"身份验证,因为您可以消除数据库往返(或者至少有一个更小的表来查询!),这反过来又可以实现水平可伸缩性。
2.防篡改客户端声明。
虽然JWT没有回答安全存储或传输等其他问题,但它不会引入任何新的安全问题。
JWT存在很多否定性,但如果你实现与其他类型身份验证相同的安全性,那么你就可以了。
最后一点说明:它也不是Cookies vs Tokens。 Cookies是一种存储和传输信息的机制,也可用于存储和传输JWT令牌。
答案 1 :(得分:25)
简短回答是:无。
较长的版本是:
在the GraphQL docs中阅读此建议后,我为会话管理实施了JWT:
如果您不熟悉任何这些身份验证机制,我们 建议使用express-jwt,因为它简单而不牺牲 任何未来的灵活性。
实施确实很简单,因为它只增加了一点复杂性。然而,过了一段时间,我(像你一样)开始想知道有什么好处。事实证明,就会话管理而言,JWT很少(或可能没有),正如本博文详细解释的那样:
答案 2 :(得分:1)
我的两美分,这与joepie91的著名博客文章形成了鲜明的对比。
考虑到(当今)(以及将来)的应用程序(主要)是云本地的
无状态JWT身份验证具有经济利益,
随着应用程序扩展而扩展:
云应用随着一口气而产生成本。
当用户不再需要“针对”会话存储进行身份验证时,可以降低成本。
处理
24/7全天候运行会话存储需要花费金钱。
在K8S的世界中,您无法摆脱基于内存的解决方案,因为吊舱是短暂的。
完全相同的原因,粘性会话不会很好。
存储
存储数据需要花费金钱。将数据存储在 SSD 中的成本甚至更高。
与会话相关的操作需要快速解决,因此无法选择光驱。
I / O
一些云提供商会为与光盘相关的I / O收费。
带宽
一些云提供商对服务器实例之间的网络活动收费。
这适用,因为几乎可以确定API和会话存储是单独的实例。
建立会话存储区
该费用甚至进一步提高了上述所有费用。
答案 3 :(得分:1)
另一个稍微不同的观点,如果您在 AWS 上可能会有用。
我们在 AWS ElastiCache 上实施了 PHP5.x 会话存储,以跨多台服务器集中存储会话。
在我们迁移到 PHP7 之前,它一直运行得很完美。为 PHP7 进行配置很困难,而且我们受到间歇性问题的困扰,对于特定用户,会话似乎“失败/不匹配/有点困惑”,然后他们无法登录该设备,直到旧会话过期。
我们转而使用 DynamoDb 来存储会话,没有更多问题。它稍微慢一些,但仅在登录(会话存储)阶段才明显。
在此过程中,我们实施了 AWS Cognito 来代替我们的身份验证,并开始使用 API-Gateway 通过 lambda python 函数传送内容。
我们使用 PHP SDK 对 Cognito 进行身份验证,然后将 JWT 存储在 cookie 中,但仍使用 PHP 会话来保持我们的旧代码正常工作。
现在我们有两个堆栈和两全其美的:PHP7 做到了这一点,并将主要内容提供给用户(非常快)。然后 JS 接管并使用 JWT 提供额外的内容。
我认为 JWT 的优点在于它可以在这两个堆栈之间传递并用于在两种情况下对用户进行身份验证。
现在我们想知道是否值得冒险并完全切换到新的 JWT 系统?
在 PHP 中,我们仍然使用旧会话,但我们也将令牌传递给 cognito 以对其进行身份验证。这可能是不必要的额外安全性,但它给人一种温暖舒适的感觉。再说一次,使用 dynamoDb 可以节省成本和维护费用。
答案 4 :(得分:0)
我在JWT和令牌+缓存之间进行用户身份验证时有一个类似的问题。
在阅读了这些文章之后,我很清楚JWT所承诺的好处并没有超过它带来的问题。所以令牌+缓存(Redis / Memcached)是我的理想选择。
Auth Headers vs JWT vs Sessions — How to Choose the Right Auth Technique for APIs
答案 5 :(得分:-1)
使用基于令牌的方法有什么优点?