三种机制的本质区别
身份认证要解决的核心问题是:”怎么证明这个请求是你?”三种主流方案:
- Cookie:服务端通过
Set-Cookie下发的小数据片段,存在客户端,随每个请求自动携带; - Session:服务端存储的会话数据,通过 Session ID(通常放 Cookie)关联到具体用户;
- JWT:自包含的签名令牌,用户信息就在 token 里,服务端验签即可,无需存储。
| 特性 | Cookie | Session | JWT |
|---|---|---|---|
| 数据存储位置 | 客户端 | 服务端(Redis/DB) | 客户端(token 本身) |
| 服务端状态 | 无 | 有(集中存储) | 无 |
| 扩展性 | 天然无状态 | 需共享存储,分布式麻烦 | 天然支持分布式 |
| 能否主动失效 | — | ✅ 删 Session | ❌ 需黑名单等机制 |
| 典型场景 | 配合 Session 用 | 传统 Web、支付等强管控 | 无状态 API、微服务、跨域 |
Session-Cookie 方案的攻防
| 攻击 | 防御 |
|---|---|
| Session 劫持 | 绑定客户端指纹(IP/UA)并校验 |
| Session 猜测 | 强随机 Session ID(≥128 位) |
| Session 固定 | 登录成功后重置 Session ID |
| XSS 窃取 Cookie | HttpOnly(JS 读不到) |
| 中间人嗅探 | Secure + 全站 HTTPS |
| CSRF | SameSite=Strict + CSRF Token |
Cookie 的三个安全属性
Set-Cookie: session_id=abc; Path=/; HttpOnly; Secure; SameSite=Strict
- HttpOnly:禁止 JS 读取,防 XSS 偷 Cookie;
- Secure:仅 HTTPS 传输,防明文嗅探;
- SameSite:控制跨站请求是否携带——
Strict只允许同站(银行类);Lax允许安全跨站跳转(默认);None允许所有跨站(必须配合 Secure)。
JWT 的安全要点

- 优点:无状态、跨域友好、微服务天然适用;
- 风险:泄露后无法主动撤销、Payload 默认不加密(别放敏感信息);
- 实践:短有效期(如 15 分钟)+ Refresh Token 续期;签名算法校验白名单(防算法混淆攻击);
- 存储:优先 HttpOnly Cookie 而不是 LocalStorage——LocalStorage 对 XSS 门户大开。
// Node.js 生成 JWT 示例
const jwt = require('jsonwebtoken');
const token = jwt.sign({ user_id: 123 }, 'secret_key', { expiresIn: '15m' });
如何选型
- 选 Session-Cookie:需要服务端严格管控会话(支付、风控)、传统单体或小型应用、需要主动踢人/改密立即可用;
- 选 JWT:无状态 API、微服务/Serverless、跨域认证(OAuth2 场景常见);
- 两者可结合:现代方案常是”JWT 做身份 + 服务端黑名单兜底主动失效”或”短 token + refresh token”组合拳。
通用安全原则:最小权限(只放必要信息)、防御纵深(HttpOnly + Secure + SameSite 组合)、异常行为监控。


