Session 与 JWT 的选择
「JWT 比 Session 先进」是个流传很广的误读。两者解决的是同一个问题——在无状态的 HTTP 上维持登录态——但取舍方向不同。
Session 的机制
用户登录后,服务端把状态存起来(内存、Redis、数据库),发一个 Session ID(通常在 Cookie 里)。后续请求凭 ID 找回状态。
- 优点:可随时踢人(删服务端记录即可),状态可查询,实现简单;
- 缺点:多实例部署需要共享存储;每次请求都要查一次。
JWT 的机制
服务端把用户信息签名后发给客户端,请求时带上,服务端验签即可,不需要存任何东西。
header.payload.signature
{"sub":"1","exp":1790000000,"role":"user"}
- 优点:服务端无状态,天然适合分布式;跨服务传递身份方便;
- 缺点:签发后无法撤销——过期前它始终有效,改密码、封号都拦不住。
关键的安全差异
JWT 放哪是个大问题。放 localStorage 会被 XSS 读走;放 Cookie 需要配 HttpOnly + Secure + SameSite。而 Session ID 一直在 Cookie 里,配合 SameSite 天然防 CSRF。
另一个坑:payload 只是 Base64 编码,不是加密,任何人都能解开看。绝不能往 JWT 里放敏感信息。
怎么选
- 单体或少数几台机器的传统站点:Session + Redis,简单可控;
- 微服务间传递身份、移动端 API:JWT(短期 + Refresh Token);
- 对登出即时性有强要求的 JWT 系统:签发短命 access token(几分钟),配合黑名单或版本号机制。
混合方案(常见落法)
access_token(JWT,5 分钟) + refresh_token(服务端存储,可撤销)
平时用 JWT 验签,不查库;撤销走 refresh token 的服务端记录;两个 token 同时过期才算真正登出。这样兼顾性能和可控性。
一句话:需要「随时能撤销」就用 Session 思路;需要「服务端不存状态」才用 JWT。按需选择,别为技术时尚买单。