为什么 JWT 明明主打“无状态、不用查库”,实际业务咋还得存个 Redis?

📅 2026/7/18 3:34:07
为什么 JWT 明明主打“无状态、不用查库”,实际业务咋还得存个 Redis?
做业务开发有时就是有些矛盾的地方比如JWT都吹它无状态又不用查数据库性能还好结果实际开发转头token就存Redis里了。JWTJSON Web Token自带用户信息和签名服务端不需要存任何东西天然支持水平扩展还能省掉昂贵的数据库查询这就是无状态架构的优雅之处。但真实业务中JWT 的最大优点无状态反倒成了它最大的缺点JWT 的设计初衷确实非常惊艳把用户 ID、权限、过期时间全塞进一串字符串里再用私钥打个签名。服务器收到后只要拿着公钥验一下签名对不对就知道这人是谁。这就像是给用户发了一张通行证卫兵只需要看证件真伪不需要打电话回总部确认。听起来都挺好但这带来了一个致命的权力真空服务端失去了对令牌的主动控制权。在真实的业务逻辑里我们对鉴权的需求不仅仅是验真更核心的需求是管控。就比如以下三个场景是纯 JWT 根本做不到的主动注销与踢人下线在 Session 模式下我们删掉 Redis 里的 Session 就行了。但在纯 JWT 模式下令牌发出去就像泼出去的水。如果用户点退出登录或者管理员想强行踢掉一个违规用户只要令牌还没到过期时间用户依然能拿着它调用你的接口。作为系统的主人是一点办法都没有啊。密码修改用户发现账号被盗紧急修改了密码。这时如果你没在后台记录令牌状态黑客手里那个还没过期的 JWT 依然是有效的。这种逻辑上的不一致性在金融或核心业务里是 P0 级的安全事故。续期问题为了安全 JWT 过期时间通常设得很短比如 30 分钟但又总不能让用户每半小时重新登录一次。为了实现这种无感续期必须引入 Refresh Token一旦涉及到 Refresh Token 的状态维护发现绕了一大圈最后还是得找个地方把它存起来。完全无状态是行不通的这时候 Redis 成了必然的选择目前主流做法主要分两个段位黑名单机制平时不去查 Redis只有当用户退出或改密码时把该 Token 的标识塞进 Redis 设为黑名单。校验时先看签名再去 Redis 瞅一眼。代价依然要查一次库JWT 的无状态优势弱了一半。白名单与状态管理这也就是大家最常用的 JWT 只是个载体Redis 里存着对应的状态。这本质上是把 JWT 当成了 Session ID 在用。看到这大家就迷惑了既然最后都要查 Redis那我直接用传统的 Session 方案不是更香吗为什么要给 Token 加上那么长的 Header 和 Payload浪费带宽我觉得 JWT 即便引入了 Redis依然有三个 Session 无法比的优势数据的内聚性JWT 里带了用户 ID、头像、昵称等基础信息。这让网关在做限流、灰度路由时不需要去查缓存就能直接拿到用户信息进行决策。这种预读取的能力对微服务集群的性能优化极其关键。跨服务的信任链几十个微服务之间跳转我们只需要传递这串 Token。只要大家都信任发证的那个 Key就不需要每个服务都去连一次 Redis 验真。只需要在网关层查一下 Redis 黑名单剩下的服务节点只验签名效率性能都很高。多端灵活度对于 App、小程序、Web 等多端混杂的场景JWT 这种放在 Authorization Header 里的方式比依赖 Cookie 的 Session 要灵活得多。