鉴权选型一旦做错,后面全是补丁。Session 与 JWT 不是谁更「现代」,而是状态放哪、如何吊销、谁来信任。
Session Cookie(服务端会话)
- 服务端存会话(Redis/DB),浏览器只持有不透明 session id。
- 吊销简单:删会话即可让用户立刻下线。
- 同站 Web 很合适;注意
HttpOnly、Secure、SameSite。
// 伪代码:登录后写入 Redis
await redis.set(`sess:${sid}`, userId, "EX", 60 * 60 * 24 * 7);
res.setHeader(
"Set-Cookie",
`sid=${sid}; HttpOnly; Secure; SameSite=Lax; Path=/`,
);JWT(尤其是 access + refresh)
- 适合多服务校验、移动端、或需要减少会话存储的场景。
- 吊销困难:未到期的 access token 默认仍然有效,需要黑名单或短 TTL。
- 别把长寿命 JWT 塞进 localStorage 当「省事方案」。
刷新与 CSRF
| 议题 | Session | JWT |
|---|---|---|
| 立即踢人 | 容易 | 难(需额外机制) |
| CSRF | Cookie 要防 | Bearer header 通常无 CSRF,但 XSS 更致命 |
| 水平扩展 | 需共享会话存储 | 校验公钥/密钥即可 |
默认建议
- 同源 Web 应用:优先 Session Cookie + 服务端会话。
- 多客户端 / 多 API 服务:短命 access token + 可吊销 refresh,旋转刷新令牌。
- 无论哪种,密码哈希、登录限流、审计日志都不要省。
小结
先写清楚威胁模型与吊销需求,再挑机制。为了「无状态」而放弃可控下线,往往不划算。