Skip to content

jwt与token+redis方案优劣

约 893 字大约 3 分钟

jwttokenredis

2025-04-21

在设计no session系统时,遇到了有两种可选方案:jwt与token+redis。

JWT: 生成并发给客户端之后,后台是不用存储,客户端访问时会验证其签名、过期时间等再取出里面的信息(如username),再使用该信息直接查询用户信息完成登录验证。jwt自带签名、过期等校验,后台不用存储,缺陷是一旦下发,服务后台无法拒绝携带该jwt的请求(如踢除用户);

token+redis: 是自己生成个32位的key,value为用户信息,访问时判断redis里是否有该token,如果有,则加载该用户信息完成登录。服务需要存储下发的每个token及对应的value,维持其过期时间,好处是随时可以删除某个token,阻断该token继续使用

但是缺点页很明显,如题所示,一旦下发便不受服务端控制,如果发生token泄露,服务器也只能任其蹂躏,在其未过期期间不能有任何措施

常见的做法是再从JWT上封装一层,提供一个类似黑名单的机制,每次访问系统时先检查此JWT令牌是否已经被拉黑,此模式虽然暂时解决了问题,但是此时你会发现,项目架构又回到了传统Session模型中,对JWT来讲属于自断招牌

这时候又凸显出了传统Session模型的好处,服务器生成令牌下发给前端,前端只持有令牌本身,而令牌代表的数据则完全由服务器说了算,此种模式下:什么Session会话、踢人下线之类的都是信手拈来,但是缺点又回来了:失去了去中心化,水平扩展比较难,且服务器需要维护所有用户的数据状态,性能压力比较大

常见解决方案也很简单,那就是把会话数据放到专业的数据中心,比如Redis, 此模式既保证了服务器对会话数据的可控性,又保证了服务水平扩展时的会话一致性


两种Token:

  1. 去中心化的JWT token
    • 优点:
      • 去中心化,便于分布式系统使用
      • 基本信息可以直接放在token中。 username,nickname,role
      • 功能权限信息可以直接放在token中。用bit位表示用户所具有的功能权限
    • 缺点:服务端无法主动让token失效
  2. 中心化的 redis token / memory session等
    • 优点:服务端可以主动让token失效
    • 缺点:每次都要进行redis查询。占用redis存储空间
  3. 优化方案
    1. Jwt Token中,增加TokenId字段
    2. 将TokenId字段存储在redis中,用来让服务端可以主动控制token失效
    3. 牺牲了JWT去中心化的特点
    4. 使用非对称加密。颁发token的认证服务器存储私钥:私钥生成签名。其他业务系统存储公钥:公钥验证签名。

方案2:redis存储的是token的白名单。用户的其他信息也要放在redis中存储。需要占用较大的redis空间和查询次数。

方案3.2 :这里的redis只存储tokenId的黑名单,同时redis也可以分布式部署,读写分离。token认证服务器操作redis的master,其他redis同步master的数据

联系我们(微信)