我不确定我是否在这里遗漏了什么,但我发现接受的答案比必要的复杂。
我看到必须点击 db 来验证或使每个 api 请求的令牌无效,但是正如我在这里看到的那样,整个过程可能会更简单。
每当创建 jwt 时,即在登录或更改/重置密码期间,将带有用户 ID 的 jwt 插入表中,并为每个 jwt 维护一个 jti(基本上是一个 uuid 号)。相同的 jti 也进入 jwt 有效负载。jti 有效地唯一标识了一个 jwt。当从多个设备或浏览器访问帐户时,用户可以同时拥有多个 jwt,在这种情况下,jti 区分设备或用户代理。
所以表模式是 jti | 用户身份。(当然还有一个主键)
对于每个 api,检查 jti 是否在表中,这意味着 jwt 是有效的。
当用户更改或重置密码时,从 db 中删除该 userId 的所有 jti。创建一个新的 jwt 并将一个新的 jti 插入到表中。这将使来自所有其他设备和浏览器的所有会话无效,但更改或重置密码的设备和浏览器除外。
当用户注销时,删除该用户的特定 jti,但不是全部。将有一个单一的登录,但没有一个单一的注销。因此,当用户注销时,他不应该从所有设备中注销。但是,删除所有 jtis 也会从所有设备中注销。
所以这将是一张表,没有日期比较。如果使用或不使用刷新令牌,情况也是一样的。
然而,为了最大限度地减少数据库干扰和可能的延迟,缓存的使用肯定有助于缓解处理时间方面的问题。
注意:如果您投反对票,请说明理由。