使用 JWT 令牌机制实现从所有设备功能注销的方法都有哪些?

Posted

技术标签:

【中文标题】使用 JWT 令牌机制实现从所有设备功能注销的方法都有哪些?【英文标题】:What are the ways to implement logout from all devices feature with JWT token mechanism?使用 JWT 令牌机制实现从所有设备功能注销的方法有哪些? 【发布时间】:2016-08-24 03:02:19 【问题描述】:

我想在我的下一个项目中实现 JWT。我只想知道是否有任何最佳方法可以在 JWT 中实现从所有设备注销。由于JWT是无状态机制,是不是一定要涉及redis/db?

【问题讨论】:

【参考方案1】:

我发现以下是使用 jwt 处理少量事情的最佳方法。

由于jwt是无状态机制,我遇到了以下问题。

如何实现注销?当有人尝试注销时,由于它是无状态的,因此会出现使令牌无效的问题。

解决方案: 使用 redis 作为处理所有令牌的内存数据库,每次用户登录时保存令牌(与令牌具有相同的 ttl),与每个请求交叉检查它以及令牌验证。当有人想注销时,连同客户端一起从redis中删除token。由于我们在redis中交叉检查,当用户注销并尝试使用相同的token访问时,系统将不会在redis中找到token,所以处理它并抛出 未经身份验证错误。

用户更改密码时,如何使同一用户的所有令牌失效?

如何实现从所有设备注销功能?

解决方案:当我们将令牌存储在 redis 中时,我们必须搜索与给定用户相关的所有令牌并将其从 redis 中删除,或者在用户登录时也将令牌存储在数据库中,找出所有与用户相关的令牌,获取令牌 ID 并将其从 redis 中删除。存储在 db 中更好,因为 dbs 更擅长查找操作。

【讨论】:

我不知道您的问题的最佳解决方案,但是一旦您将令牌存储在服务器的内存中,您就不再拥有无状态身份验证机制。这对您来说可能没问题,但如果您需要扩展到多台服务器,您仍然会遇到传统的“会话亲和性”问题 是的..!我同意,但是解决上述问题的方法是什么?这些是每个应用程序应实现的最低功能 为什么您在更改密码以及从所有设备调用注销时不搜索并删除与该用户相关的所有令牌?这样你就可以保持无国籍状态 如果令牌存储在内存中,我如何删除它们?【参考方案2】:

我们可以在创建新用户时在数据库中保存一个随机的 JWT 密码吗?如果我们要注销所有设备,只需生成新的 Secret,因此所有 OLD Token 现在都无效了。而对于正常的注销,只需删除前端的令牌

【讨论】:

我会说添加一个要存储的随机盐,而不是随机密钥。 您可以只存储时间戳,其中包含在该时间戳之前生成的所有令牌均无效的规则【参考方案3】:

如果你只是想删除令牌,就像从前端应用程序中删除它一样简单,在你的情况下清除存储令牌的cookie

另一方面,如果您要使令牌无效,有几种方法可以做到这一点,以下是一些方法

(1) 如果生成的所有令牌都存储在后端,这就像清除存储一样简单,如果令牌已映射到用户,您只需清除特定用户的令牌.

(2) 您可以添加一个日期字段,如“invalidate_before”以及 user,在更改密码时应更新该字段,从所有设备注销等。 只需在此类事件上将 invalidate_before 更新为 currentTime()。 每次创建新令牌时,在令牌有效负载中添加创建时间, 要在传入请求中验证令牌,只需检查有效负载中的创建时间是否大于该用户在 db 中的 invalidate_before 时间

(3) 当您创建新用户时,仅为该用户创建一个秘密,然后您可以使用该特定秘密签署每个用户令牌,就像在 (2) 中一样 更改密码、从所有设备注销等事件应该创建一个新的秘密。 这样您也可以通过检查令牌签名来使其无效。

(2)(3) 的开销是,验证将是一个 2 步过程,它涉及数据库读取

编辑:对于 (3),您可以改用盐(最终秘密将是 通用秘密 + 特定用户的盐),这样您就有办法通过更改 salt 使单个用户的令牌或通过更改公共密钥使所有用户的令牌无效

【讨论】:

以上是关于使用 JWT 令牌机制实现从所有设备功能注销的方法都有哪些?的主要内容,如果未能解决你的问题,请参考以下文章

使用 JWT 管理多个设备节点 js 的用户会话

强制过期 JWT

jwt令牌过期后如何注销

使用 JWT 令牌使用 AdonisJS 注销

在移动设备上使用 JWT auth 离线注销

JWT 令牌登录和注销