在注销时使JWT失效?

3
我对JWT还不熟悉,想知道在用户从应用程序注销时是否可能在服务器端使JWT无效(我也想知道这样做是否有意义!)。想法是:
  1. 用户在其应用程序中点击注销链接
  2. 应用程序调用 POST https://api.myapp.example.com/auth/invalidate
  3. JWT(在HTTP请求头中的授权/承载令牌)被某种方式失效
  4. 现在,没有人可以再次使用该JWT
我不确定这是否是一种非正统的注销逻辑方法,或者是否可以让JWT在用户注销后继续保持有效(我想我可以将JWT到期时间缩短为60分钟左右)。
所以,我想知道是否可能使用这种“无效化”方式(如果可以,如何实现),以及是否有意义这样做(如果没有,典型的注销流程是什么?)。谢谢!

1
你刚刚指出了使用JWT进行登录认证的一个缺陷(在我看来)。令牌本身包含了过期时间,你无法修改其过期时间而不创建全新的令牌。你可以添加一个辅助系统,使服务器能够根据特定条件拒绝令牌,但这就回到了传统的登录系统,你失去了访问令牌的可移植性。你可以简单地从客户端删除令牌,但你不能确定用户是否保留了它并在注销后尝试再次使用它。 - Kaddath
1个回答

4
除了在exp声明中说明的令牌到期日期外,我可以想到几种使JWT令牌失效的方法:

更改密钥

第一种方法需要在服务器端更改用于签署令牌的密钥,但似乎不适用于您问题中描述的情况。

将令牌标识符列入白名单

另一种方法(可能更适合您的方法)是在服务器端中记录令牌并将其列入白名单。

  • 在发放令牌时,请使用jti声明来存储令牌中的唯一标识符。并在服务器端将此唯一标识符添加到白名单中。

  • 验证令牌时(除了检查签名、到期日期和其他必要的声明之外),请确保jti声明的值已列入白名单。

  • 当用户请求使令牌失效时,请从白名单中删除令牌标识符。

对于令牌标识符,您可以使用UUID

JWT允许您执行无状态身份验证(一旦验证了签名,您就可以信任该令牌并且不依赖于外部实体进行身份验证)。白名单方法是一个权衡,在需要跟踪您已发出的令牌时使用。


谢谢@Cassio (+1)。我认为我喜欢你的白名单/令牌ID方法。如果您不介意,我有两个快速的后续问题:**(1)** 在上面,您说“虽然这并不是真正的无状态”,好像采用这种解决方案会创建问题或违反某些原则。您能否详细说明一下?也就是说:为什么JWT“有状态”是“不好”的?**(2)** 我假设对于白名单,我可以使用任何我想要的东西:MySQL数据库表等。是吗?再次感谢! - smeeb
@smeeb (1) 我的陈述应该是“那不是真正的无状态身份验证”。JWT的一个巨大优势是它是一个自包含的令牌,允许您执行无状态身份验证。也就是说,一旦您验证了签名,您可以信任该令牌并在不依赖外部实体的情况下执行身份验证。但是,如果您需要使特定令牌失效,则应该跟踪它(例如使用白名单方法)。 - cassiomolin
@smeeb (2) 对于白名单,您可以使用最适合您的内容:SQL或NoSQL数据库。您可能还希望将到期日期与令牌标识一起存储,以便删除已过期的令牌的标识符。 - cassiomolin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接