10

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

4

3 回答 3

8

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

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

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

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

  • 用户更改密码时如何使同一用户的所有令牌无效

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

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

于 2016-04-29T06:00:37.380 回答
3

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

于 2020-06-23T01:50:03.070 回答
2

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

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

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

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

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

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

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

于 2021-08-07T12:14:02.633 回答