登录态方案怎么选?JWT 与集中式 Session 各有什么优劣?
结论先行:有状态与无状态之争。集中式 Session(Redis 存会话)是“服务端说了算”,登出/封禁即刻生效,适合高安全内部系统;JWT 是“客户端自证”,服务端无状态、天然适合跨域与水平扩容,但签发后难以主动作废。规模大了两者常结合:短时 access token + refresh token。
一、两种方案对比
| 对比项 | Session + Redis | JWT |
|---|---|---|
| 状态存储 | 服务端 Redis | 客户端携带,服务端不存 |
| 水平扩容 | 依赖共享 Redis(本就集中) | 天然无状态,随意扩 |
| 主动登出/封禁 | 删 session 即生效 | 难以作废,需黑名单 |
| 跨域/跨端 | 需配 cookie 域或透传 token | Header/移动端都方便 |
| 安全面 | 主要是 sessionId 泄露 | token 泄露 + 密钥泄露 |
| 开销 | 每次查 Redis | 免查询,但验签有 CPU 开销 |
| 多端互踢 | 删 session 即生效 | 需额外维护在线状态 |
二、什么时候选哪个
- 后台管理系统、金融类:选 Session + Redis,能踢人、能审计、失效可控。
- 开放 API、小程序、多端:选 JWT,无状态、易水平扩容。
- 高安全双 token:access token 短时效(15~30 分钟)+ refresh token 长时效轮换。
- 演进路径:纯 session → 共享 Redis session → 双 token,每步都在扩容与安全之间做取舍。
登录成功 → 签发 access + refresh
access 过期 → 用 refresh 换新 access(refresh 可被吊销)
access 泄露影响面 = 短窗口;refresh 泄露 → 检测异常即吊销重登
三、各自常见的坑
- Session:Redis 挂掉全员掉线 → 会话存储要高可用;sessionId 放 cookie 有 CSRF 风险 → SameSite/Token 化。
- JWT:密钥写进代码库、不校验算法(alg=none 攻击)、payload 塞太大(超过 Header 上限)。
- 刷新令牌风暴:并发请求同时带过期 access 去换新 → 加锁或用短期 refresh 缓存。
- Session 的坑(续):别把大对象塞进 session,只放 userId/角色等,其余详情查库。
常见追问与记忆点
- 追问:JWT 可以放进 cookie 吗?可以,但要注意 CSRF 与大小限制,移动端/跨域更常用 Authorization Header。
- 追问:SSO 单点登录一般怎么搭?统一认证中心发授权码/ticket,各系统换 token,会话集中到认证中心。
- 追问:混合方案里 Redis 存什么?双 token 的黑名单、刷新记录、风控标记,等于给 JWT 补上有状态底座。
- 记忆点:要能踢人、能封禁选 Session 集中式;要无状态、好扩容选 JWT;生产用“短 access + 可吊销 refresh”两头补。