JWT 怎么解决用户被禁用的问题?

使用 JWT 作为用户登录认证的时候,是否需要每次都通过 jwt payload 里面的信息(如 ID)来通过数据库查询出用户?

否则怎么判断当前用户是否已经被禁用、删除、角色权限变化等信息,直接使用 jwt payload 里面的信息很可能已经过时?

阅读 2.1k
avatarAI BotBETA

JWT (JSON Web Tokens) 是一种开放标准 (RFC 7519) 定义的方式,用于在网络之间安全地传输信息。这些信息可以用于验证、授权、信息交换等。

关于你的问题,这里有一些可能的解决方案。

  1. 数据库查询:是的,一种常见的方法是在每次发送请求时通过 JWT 的 payload 信息查询数据库以获取用户信息。这可以确保你拥有关于用户的最准确信息,包括他们的角色、权限以及是否被禁用。这需要数据库的配合,可以在每次验证 JWT 时,同时查询数据库进行用户信息的校验。
  2. 刷新令牌(Refresh Tokens):你可以使用一个刷新令牌机制来解决这个问题。基本思路是,当用户登录时,他们将获得一个 JWT 和一个对应的刷新令牌。如果 JWT 过期或无效,他们可以使用刷新令牌来获取新的 JWT。在这个过程中,你可以在后台查询数据库以检查用户的状态,如果用户被禁用,你可以拒绝他们的请求或为他们生成一个新的、无效的 JWT。
  3. 使用密钥库:另一种方法是使用密钥库来存储用户的状态信息。在这种情况下,JWT 不仅会包含用户信息,还会包含一个指向密钥库的引用。当 JWT 被验证时,你可以从密钥库中获取用户的状态信息。如果用户的状态已经改变(例如,他们已被禁用),你可以拒绝 JWT 的验证。

在选择最佳方法时,你需要考虑你的应用程序的具体需求和限制。例如,频繁查询数据库可能会影响性能,而使用刷新令牌可能会增加复杂性并需要额外的安全措施(例如,刷新令牌需要被加密或安全地存储)。

5 个回答

首先使用JWT的目的就是做服务端无状态,不想在服务端存储与用户Session有关的数据。而JWT内容仅是简单的Base64编码,故不宜存储敏感信息。一般存储用户ID,或者与用户ID唯一映射的一个字符串(隐藏数据库真实用户ID)。

再回到问题本身,可以考虑使用缓存的方式。比如有个专门封装的校验是否被禁用? 是否被删除? 权限是否发生变化?的服务。这个服务只是网关层的一个小模块,具体实现可依赖Redis等缓存,加快校验速度。

假设Redis里面存储有 被禁用账号列表? 每次查询一下当前账号是否被禁用。若数据量较大时,还可进行分桶?布隆过滤器等手段优化。

延伸一下,这个流程很适合使用责任链设计模式啊。

附加信息比较多,感觉难以做一个通用的解决方案,大概率要根据实际业务来做具体设计。

jwt只放用户标识类信息,过多的信息不需要都放在里面,如果需要查询更新用户信息,查redis/数据库里。redis/数据库做好同步

一般项目中 jwt不放敏感的信息,通常只是放个userId,封禁,等一系列的变化都是通过userId 去关联查询,而且这些关联信息会存储在缓存中,避免给数据库造成压力

所以说jwt虽然看着美好,但并不是特别实用,像是楼中说的各种加redis数据库二次验证的,但是jwt当初设计就是为了不再走这些验证,现在又加上了,那我干嘛还用jwt,我直接返回一个token不好吗,还加密解密搞这么麻烦干嘛。
实在是想解决禁用问题,只能是和楼中说的加黑名单二次验证。

新手上路,请多包涵

jwt 比较切实的作用就是安全的分发信息,就普通的业务而言,就是我不用查数据库就知道用户 id 和用户名是多少,但涉及到鉴权等其它方面就和普通 token 字符串无差别。

安全地分发信息这一点,苹果应用商店的 StoreKitV2 分发交易信息的场景是我认为非常 OK 的:用 ES256 为交易信息签名,我们的业务端使用公钥验签。提升了效率、保障了安全。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题