JJWT 可以使 server-side 上的令牌无效吗?

Can JJWT invalidate tokens on the server-side?

我是 JWT 的新手,想知道当用户退出应用程序时是否可以在 server-side 上 invalidate/void JWT(我也想知道它是否甚至可以这样做是有意义的!)。思路是:

  1. 用户在他们的应用程序中点击退出 link
  2. 应用调用 POST https://api.myapp.example.com/auth/invalidate
  3. JWT(它是 HTTP 请求 header 中的 authorization/bearer 令牌)以某种方式无效
  4. 现在,再也没有人可以使用那个 JWT

我不确定这是否是注销逻辑的非正统方法,或者即使在用户注销后让 JWT 仍然有效是否可以接受(我想我可以缩短JWT 到期时间为 60 分钟或其他时间)。

再说一遍:想知道是否可以使用 JJWT 来做这种 "invalidation"(如果可以,怎么做?!),以及这样做是否有意义(如果没有,什么典型的注销流程是什么样的?!)。谢谢!

这是 JWT 的核心缺点之一——它们是独立的令牌,这意味着没有固有的方法可以使它们失效。最多,您可以创建一个令牌 ID (UUID.randomUUID()) 并尝试维护一个撤销列表,但随后您又需要 JWT 应该让您摆脱的大部分基础设施。

您不会使 JWT 失效,JWT 是不可变的。令牌的有效性取决于到期时间和签名密钥,在严重的安全事件中,您可以更改签名密钥,然后已颁发的令牌将失效。你也可以在数据库中使用令牌黑名单,但这将花费另一次数据库访问,如果你使用它,身份验证流程将不再是无状态的。

一旦用户注销,则必须从存储令牌的客户端删除令牌,通常令牌的存储是浏览器的cookielocalStorage

其他答案是正确的,因为您通常不需要 sign-out/invalidate 端点。用户从您的应用程序注销意味着您只需从本地存储中删除 his/her 令牌。

如果您仍然决定实施令牌失效端点,您可以通过跟踪包含无效令牌 ID 的 "blacklist" 来实现:

  • 当用户调用端点时,您将令牌的 ID 添加到黑名单。
  • 对于每个经过身份验证的请求,您首先检查令牌的 ID 是否包含在黑名单中并相应地拒绝访问。
  • 确保 old/obsolete 黑名单条目被自动清理,不会占用你的内存。
  • 但是还要确保黑名单条目的 time-to-live 至少与令牌的有效期一样长。

对于实现,您不一定需要数据库,您可以使用内存中的自过期映射,如 f.i。 guava's CacheBuilder or one of the alternatives discussed in this thread