我已经阅读了很多关于JWT以及如何通过JWT创建“无状态”会话的内容。我所理解的要点是因为签名和&到期时,您基本上可以发送整个会话以供客户端保存,并且服务器不必维护数据库来记住会话。
我不明白的是,如果您的用户需要注销,或者您需要在到期前使会话无效,会发生什么?
从技术上讲,您可以指示浏览器从客户端删除它,但您无法确定这实际发生了。令牌本身在技术上仍然有效,如果没有遵循删除说明,它仍然可以使用。
这种理解是否正确?如果是这样,这对客户端会话管理来说不是一个大错吗?除了让服务器存储会话或缩短过期时间之外,还有什么方法可以克服这个问题吗?
答案 0 :(得分:14)
有几个原因使JWT令牌在到期时间失效:帐户被删除/阻止/暂停,密码已更改,权限已更改,用户已由管理员注销。所以你的问题是主题
根据您的使用情况,有几种技术可以应用或组合
1)从本地存储中删除客户端令牌
2)令牌黑名单:存储在注销和放大之间的令牌到期时间,标记已过期并在每个请求中检查。使用唯一标识符jti
或包含上次登录日期并在iat
发布以删除旧令牌
需要服务器存储。如果您不希望撤销太多令牌,您也可以使用内存中的黑名单。您只需在更新用户和currentTime - maxExpiryTime < lastLoginDate (iat)
上的关键数据后设置条目。 currentTime - maxExpiryTime > lastModified
(不再发送未过期的令牌)时,可以丢弃该条目。在这种情况下,不需要存储整个令牌。只需sub
,iat
,也许jti
3)到期时间缩短并旋转它们。每隔几个请求发出一个新的访问令牌。使用 refresh tokens 允许您的应用获取新的访问令牌,而无需重新进行身份验证并与sliding-sessions
滑动会话是在一段时间不活动后过期的会话。当用户执行操作时,将发出新的访问令牌。如果用户使用过期的访问令牌,则会话被视为非活动状态,并且需要新的访问令牌。可以使用刷新令牌或需要凭证
来获取此新令牌如果帐户受到新用户和密码登录的影响,则允许更改用户唯一ID
要在用户更改密码时使令牌无效,请使用密码哈希对令牌进行签名。如果密码更改,则以前的任何令牌都将自动无法验证。使用其他感兴趣的字段扩展此机制以进行签名。缺点是它需要访问数据库
更改签名算法以撤消主要安全问题中的所有当前令牌
答案 1 :(得分:2)
我做了一些功课,似乎更好的实现撤销的方法是使用jti(jtw上的id)和撤销id的黑名单(当令牌过期时将被清除)。这使得JTW成为唯一的黑名单部分。
答案 2 :(得分:0)
黑名单 是JWT无国籍违规行为。您可以使用许多身份验证方案。 JWT基于无状态,因此应该以这种方式使用。另一方面,它是非常常见的身份验证方案,如果您必须实现它,并且如果您希望您的应用程序(API)真正安全,则必须允许一些自定义。
我个人在我的项目中使用这两种方法(根据性能需求单独或组合):
令牌日志。我记录了我的项目中发出的每个令牌,ID,声明,到期,我确实在每个请求上验证它。如果令牌已过期,它将从此日志移至归档。性能下降并不是那么可怕。
除了用户名称之外,我还添加了声明用户秘密的散列(类似于自动生成的隐藏令牌或密码),当从dbo加载用户时,该声明在下一步中被授权。这没有显着的性能下降,因为无论如何都要执行用户查询。缺点是您不能使具体令牌无效,只能使用户的所有会话无效。