我将用户角色存储在JWT中(以限制API端点)。管理员可以更改角色。
如果角色发生变化。我怎么能在所有代币中反映这一点?我考虑过几个解决方案:
如果我使用刷新令牌,则用户必须等到访问令牌的到期日期过期。
我可以记录已更改的用户ID并检查每个请求,然后在用户更改后返回新令牌。
有没有一种标准方法可以做到这一点?
答案 0 :(得分:8)
JWT令牌是不可变的,因此您无法更改/更新现有令牌的声明 - 因此您必须发出新的JWT令牌。
这导致了JWT的最大问题 - 令牌撤销。没有好的解决方案。你能做的是
保持JWT到期日期短(并可选择使用刷新令牌)
使用黑名单保留已撤销令牌的列表(当然会以这种方式丢失'无状态'部分)
更改密钥(请记住,这会撤消所有用户的所有有效令牌)
最佳解决方案取决于具体案例。
答案 1 :(得分:6)
如果您关心即时更改,刷新令牌似乎不是解决方案,如果您撤销其权限,您可能不希望用户访问审核工具一段时间。< / p>
你可以做的是在jwt令牌中保留一个相对于用户的版本号,就像mongoose对它的versionKey一样。通过这样做,您将能够针对给定用户的数据库中的版本检查此版本。每次更改此用户的角色时,如果jwt的版本不匹配,您将增加此版本,只需重新创建具有正确角色和版本的新版本,然后将其发送回用户。
我不相信这有一个合适的标准,因为jwt在设计上是不可变的,如果你需要更新&#34;你必须完全改变它。它
答案 2 :(得分:0)
要解决这种情况,您可以缩短令牌的寿命,一旦令牌过期,您可以在进行隐式授予的情况下静默续订令牌,或者使用刷新令牌机制从授权服务器发行新令牌。角色更改后,它可能不会立即反映在令牌中,但是在令牌更新后将可用。
答案 3 :(得分:0)
@Janar说,三种解决方案可以处理不同的情况,但是它们仍然存在相应的缺点。
我还想撤销您的令牌:
iat
设置为JWT有效负载。 (您应该知道什么是iat
)答案 4 :(得分:-1)
对此的解决方案是在使用 JWT 令牌时将身份验证和授权分开。使用令牌进行身份验证(声明 ID)并使用该 ID 检查数据库中的授权。考虑到您现在必须检查每个请求的授权,这可能会增加每个请求的延迟。但是,这可以通过使用内存数据结构存储(例如 Redis)作为缓存来缓解。在每次权限更改时,删除缓存并再次调用权限。