使客户端 JWT 会话无效

Invalidating client side JWT session

我阅读了很多有关 JWT 以及如何通过 JWT 创建 "stateless" 会话的内容。我理解的要点是,由于签名和过期,您基本上可以发送整个会话以供客户端保存,而服务器不必维护数据库来记住会话。

我不明白的是,如果您的用户需要注销,或者您需要在到期前使​​会话无效,会发生什么情况?

从技术上讲,您可以指示浏览器从客户端删除它,但您不能确定这是否真的发生了。令牌本身在技术上仍然有效,如果没有遵循您的删除说明,它仍然可以使用。

这个理解对吗?如果是这样,这不是客户端会话管理的一个巨大错误吗?除了让服务器存储会话或缩短过期时间之外,还有什么方法可以克服这个问题吗?

我做了一些功课,似乎实现撤销的更好方法是使用 jti(Jtw 上的 id)和撤销 id 的黑名单(令牌过期时将被清除)。这使得 JTW 仅对黑名单部分有状态。

在到期时间之前使 JWT 令牌失效的原因有多种:帐户 deleted/blocked/suspended、密码已更改、权限已更改、用户被管理员注销。所以你的问题是关于主题

根据您的用例,可以应用或组合多种技术

1) 从本地存储

中删除客户端令牌

2) 令牌黑名单: 存储在注销和过期时间之间的令牌,标记过期并在每个请求中检查它。使用唯一标识符 jti 或包括上次登录日期并在 iat 发布以删除旧令牌

需要服务器存储。如果您不希望撤销太多令牌,您还可以使用内存中的黑名单。您只需要在更新用户和currentTime - maxExpiryTime < lastLoginDate (iat)‌ 上的关键数据后设置一个条目。当 currentTime - maxExpiryTime > lastModified(不再发送未过期的令牌)时,可以丢弃该条目。在这种情况下不需要存储整个令牌。只是 subiat,也许 jti

3) 缩短到期时间并轮换它们。 每隔几个请求发出一个新的 访问令牌 。使用 让您的应用程序获取新的访问令牌而无需重新验证并与 sliding-sessions

结合

滑动会话是指在一段时间不活动后过期的会话。当用户执行操作时,会发出一个新的访问令牌。如果用户使用过期的访问令牌,会话将被视为不活动,需要新的访问令牌。这个新令牌可以通过刷新令牌或需要凭据获得

其他常用技巧

  • 如果帐户被新用户和密码登录泄露,允许更改用户唯一 ID

  • 要在用户更改密码时使令牌无效,请使用密码的哈希值对令牌进行签名。如果密码更改,任何先前的令牌将自动无法验证。将该机制扩展到其他感兴趣的领域来签名。缺点是需要访问数据库

  • 更改签名算法以撤销重大安全问题中的所有当前令牌

看看Invalidating JSON Web Tokens

黑名单 JWT 无状态违规。您可以使用许多身份验证方案。 JWT 是基于无状态的,所以应该这样使用。另一方面,这是非常常见的身份验证方案,如果您必须实施它,并且如果您希望您的应用程序 (API) 真正安全,则必须允许进行一些自定义。

我个人在我的项目中使用这两种方法(单独或组合,取决于性能需求):

  1. 令牌日志。我确实记录了我项目中发布的每个令牌,包括 ID、声明、到期时间,并且我确实在每个请求上对其进行了验证。如果令牌过期,它将从此日志移至存档。性能下降并没有那么糟糕。

  2. 除了用户名之外,我还在声明中添加了用户秘密的散列(类似于自动生成的隐藏令牌或密码),当从 dbo 加载用户时,它在下一步中被授权。这没有显着的性能下降,因为无论如何都会执行用户查询。缺点是您不能使具体令牌无效,只能使所有用户的会话无效。