面试中被嘲笑 Token 放在 Redis 里?——JWT 无状态的四个致命场景与解法
整理 JWT 无状态设计的边界:主动吊销、封禁、改密踢人与 token 过期吞表单四个致命场景,以及黑名单、白名单和双 Token 续期的对应解法与面试应答思路。
本文整理自微信公众号「小哈学Java」的文章《面试中被嘲笑 Token 放在 Redis 里?这把给我干沉默了…》。
一句话梗概:面试被问”登录认证怎么做”,你说”Token 放 Redis 里”,面试官笑了,说你不懂 JWT 的无状态设计。文章讲清楚 JWT 是什么、四个致命场景、为什么要把 Token 放 Redis、以及面试到底该怎么答。
JWT 到底是什么
JWT(JSON Web Token)是一段用点号分成三段的字符串:Header(算法类型)、Payload(用户信息)、Signature(签名)。三段都是 Base64 编码后用点号连接。
JWT 是签名,不是加密——任何人拿到 token 都能解码看内容,所以密码绝不能放进去。
JWT 认证完整流程
登录成功 → 服务端签发 Token → 客户端保存(一般放 localStorage)→ 每次请求在 Header 带 Authorization: Bearer <token> → 服务端验签 → 从 Payload 取用户信息。
全程不查数据库、不查 Redis,自给自足,这就是”无状态”的意思。
四个致命场景(重点)
纯 JWT 的”无状态”上线后会暴露四个问题:
| 场景 | 问题描述 | 对应解法 |
|---|---|---|
| 场景一:账号被盗,无法立即踢人 | Token 有效期 2 小时,还剩 1 小时 45 分。想让这个 token 立刻失效,纯 JWT 做不到——已签发的 token 在过期前一直有效。 | 黑名单(主动吊销) |
| 场景二:封禁用户不生效 | 账号被封了,但用户手里的 token 还能继续用。 | 黑名单/白名单 |
| 场景三:改密码不踢其他设备 | 用户改密码后想让其他设备全部失效,纯 JWT 做不到。 | 白名单 |
| 场景四:token 过期吞表单 | 用户填了 20 多分钟的表单,点提交时 token 过期了,整个内容全丢。 | 双 Token 续期 |
对应解法
解法 1:把 Token 放 Redis(黑名单)
解决主动吊销最直接的方案是黑名单。用户被踢下线时,把 token 加进黑名单;每次请求先查黑名单,在里面就拒绝。
黑名单存哪?内存不行(多台服务器不共享、重启就丢)、数据库太慢(每个请求查一次受不了)→ 所以放 Redis。Redis 只存”已失效”的 token,平时没什么写入,查询也快,用 SET 加黑名单、验签前先查。
解法 2:白名单(更彻底)
直接把 token 存 Redis,每次验证都去 Redis 查。这和传统 Session 没太大区别,只是借了 JWT 格式当 Session ID 用。
| 维度 | JWT + 黑名单 | token 存 Redis(白名单) |
|---|---|---|
| 是否无状态 | 基本无状态(正常请求不写 Redis) | 有状态(每次请求都依赖 Redis) |
| 能否主动吊销 | 能(踢人时加黑名单) | 能 |
| 代价 | 轻量,只有踢人才写 | 控制力更强,可限制同时在线设备数、实时查看在线状态,但每次请求都查 Redis |
结论:黑名单相对轻量,多数业务选这个;白名单控制力更强,适合需要限制在线设备数/实时看在线状态的场景。
解法 3:双 Token 续期方案(针对”场景四”等过期问题)
双 Token 续期专门解决”场景四:token 过期吞表单”这类问题——用户填了 20 多分钟表单、点提交那一刻 token 刚好过期、内容全丢,纯 JWT 只能让用户被迫重新登录。
- AccessToken:有效期短(30 分钟),做实际鉴权。
- RefreshToken:有效期长(7 天),只用来换新的 AccessToken。
AccessToken 过期后,前端用 RefreshToken 无感换新;RefreshToken 存 Redis,用户改密码就删掉,让他下次操作时重新登录(这同时补上了”场景三”里改密码踢其他设备的能力)。
解法 4:应对”Redis 单点故障”质疑
面试官常质疑”token 都放 Redis,Redis 挂了怎么办”。Redis 高可用方案成熟:主从复制、Sentinel(哨兵,主节点挂了自动选新主)、Cluster(集群,数据分片横向扩展)。
面试官到底在嘲笑什么(两种情况)
- 第一种(要改方案):你用了 JWT 但验证时完全不走签名,每次都去 Redis 查 token 是否存在。这等于只借了 JWT 格式、没用它的能力——不如直接生成随机字符串当 Session ID,还省了编解码开销。面试官嘲笑的是这里。
- 第二种(要改表达):你确实有业务需求需要主动吊销,选了 JWT+Redis 方案,但面试里只说了”放 Redis”、没说为什么,导致面试官误以为你不懂无状态设计。
纯 JWT 什么时候真的合适
- 一次性凭证:邮箱验证链接、密码重置链接、临时分享链接——签一次用一次,不需要续期和吊销。
- 跨服务调用:网关层做一次验签,用户信息往下游传;订单、支付服务直接从 JWT 取 userId,不用再查 Redis。此时 JWT 承担的是身份传递角色,不是管理登录会话。
面试怎么答(总结)
- 别上来就说”放 Redis”,也别上来就说”JWT 无状态”。
- 先说业务需求:需不需要主动踢人?改密码后其他设备需不需要立刻失效?需不需要限制同时在线设备数?
- 再根据需求说方案:需要 → 选 JWT+Redis 黑名单,说清楚纯 JWT 做不了主动吊销;不需要 → 纯 JWT 够了,说清楚签名验证流程和密钥管理。
- 面试官真正想听的不是你选了哪个,而是你知不知道每个方案的边界。 “Token 放 Redis”本身没问题,问题在于说不出来为什么放。
一句话收尾:JWT 的价值在无状态鉴权(验签即用、跨服务传递),但代价是无法主动吊销;要”踢人/封禁/改密强制下线”,就得用 Redis 做黑名单或白名单来补上控制力。 面试时把”为什么”讲清楚,被嘲笑的问题就变成了加分项。