1. JWT 基础回顾
1.1 JWT 结构:三段的秘密
JSON Web Token(JWT)是一种紧凑的、URL 安全的令牌格式,由三个 Base64URL 编码的部分通过点号(.)连接而成:
// JWT 令牌示例
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
| 部分 | 名称 | 内容说明 | 是否加密 |
|---|---|---|---|
| Header | 头部 | 令牌类型(typ)和签名算法(alg),如 HS256、RS256 | 仅 Base64URL 编码,明文 |
| Payload | 载荷 | 声明(Claims):用户 ID、角色、过期时间(exp)、签发时间(iat)等 | 仅 Base64URL 编码,明文 |
| Signature | 签名 | 对 Header + "." + Payload 使用指定算法和密钥生成的签名 | 防篡改 |
⚠️ 安全提示:Payload 仅经过 Base64URL 编码,并未加密。切勿在 Payload 中存放密码、信用卡号等敏感信息。如需加密载荷,应使用 JWE(JSON Web Encryption)标准。
1.2 JWT 工作原理:无状态认证流程
JWT 的核心价值在于无状态(Stateless):服务端无需存储会话信息,令牌自身携带所有必要数据。其典型工作流程如下:
- 用户登录:客户端提交用户名/密码到认证服务。
- 签发令牌:服务端验证凭据后,生成 JWT 并返回给客户端。
- 携带令牌:客户端在后续请求的 HTTP Header 中携带
Authorization: Bearer <token>。 - 验证令牌:服务端中间件解析 JWT,验证签名和过期时间,提取用户身份与权限。
- 授权决策:根据 Payload 中的角色/权限声明,决定是否放行请求。
1.3 JWT vs Session:核心对比
在分布式后端架构中,JWT 与传统的 Session 认证方式各有优劣。下表从多个维度进行对比:
| 对比维度 | JWT(无状态令牌) | Session(有状态会话) |
|---|---|---|
| 存储位置 | 令牌存储在客户端,服务端无状态 | 会话数据存储在服务端内存/Redis |
| 扩展性 | 天然支持水平扩展,无需共享存储 | 需要集中式会话存储(如 Redis) |
| 性能 | 验证只需计算签名,无 I/O 开销 | 每次请求需查询会话存储,有网络延迟 |
| 安全性 | Payload 明文,需 HTTPS 传输;无法主动吊销 | 服务端可控,可随时销毁会话 |
| 令牌大小 | 较大(通常 500B~2KB),含完整声明 | 仅传递 Session ID(通常 16~32 字节) |
| 吊销机制 | 需配合黑名单或短过期时间 | 直接删除会话记录即可 |
| 跨域支持 | 天然支持跨域(CORS) | 需配置跨域 Cookie 或额外处理 |
📌 选型建议:
- 微服务架构、API 网关场景:优先选择 JWT,减少服务间耦合。
- 传统单体应用、需要即时吊销:Session 方案更简单可控。
- 混合方案:使用 JWT 做身份认证,同时维护短生命周期的 Refresh Token 和 Redis 黑名单,兼顾无状态与安全性。
1.4 JWT 的常见算法选择
| 算法 | 类型 | 密钥 | 性能 | 适用场景 |
|---|---|---|---|---|
| HS256 | 对称加密 | 单一共享密钥 | 极快 | 单体应用、内部服务 |
| RS256 | 非对称加密 | 私钥签名,公钥验证 | 较慢(签名慢,验证快) | 微服务、第三方认证 |
| ES256 | 椭圆曲线非对称 | 私钥签名,公钥验证 | 快(比 RSA 更高效) | 移动端、IoT 设备 |