1. JWT 基础概念
1.1 JWT 结构:三部分拆解
JSON Web Token(JWT)是一种紧凑的、URL 安全的令牌格式,由三个 Base64URL 编码的部分通过点号(.)连接而成:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
| 部分 | 名称 | 内容说明 | 是否加密 |
|---|---|---|---|
| Header | 头部 | 令牌类型(typ)和签名算法(alg),如 HS256、RS256 | 仅 Base64URL 编码,明文 |
| Payload | 载荷 | 声明(claims):用户标识、过期时间(exp)、签发时间(iat)等 | 仅 Base64URL 编码,明文 |
| Signature | 签名 | 对 Header + Payload 使用密钥或私钥生成的防篡改摘要 | 不可逆,依赖密钥 |
关键认知:JWT 的 Payload 是明文可读的,不要存放密码、手机号等敏感信息。签名只保证数据未被篡改,不提供加密。
1.2 JWT 工作原理
JWT 的工作流程围绕“签发 → 传输 → 验证”三个环节展开,核心是无状态认证:
- 签发(Issuing):用户登录成功后,服务端生成 JWT,使用密钥对 Header 和 Payload 签名。
- 传输(Transport):客户端收到 JWT 后,通常存储在 localStorage 或 Cookie 中,后续每次请求在 HTTP 头部携带
Authorization: Bearer <token>。 - 验证(Verification):服务端收到请求后,从头部提取 JWT,使用相同密钥验证签名完整性,并检查 Payload 中的
exp(过期时间)等声明。
最佳实践:JWT 应使用 HTTPS 传输,防止中间人截获。前端存储推荐使用 httpOnly Cookie + CSRF Token,避免 XSS 窃取。
1.3 JWT 与 Session 对比
Session 认证是服务端有状态方案,JWT 是无状态方案。两者在扩展性、存储、安全性等方面存在显著差异:
| 对比维度 | Session 认证 | JWT 认证 |
|---|---|---|
| 状态存储 | 服务端内存 / Redis / 数据库 | 客户端令牌本身,服务端无状态 |
| 扩展性 | 需要共享 Session 存储(如 Redis 集群) | 天然支持水平扩展,无需共享存储 |
| 跨域支持 | 需配置 CORS + Cookie 跨域策略 | 通过 Authorization 头部,跨域友好 |
| 吊销能力 | 直接删除 Session 即可立即失效 | 需维护黑名单或缩短过期时间 |
| 数据体积 | Session ID 很小(通常 32 字节) | JWT 体积较大(通常 500 字节以上) |
| 安全风险 | CSRF 攻击(依赖 Cookie) | XSS 攻击(令牌被窃取) |
选型建议:单体应用或对即时吊销有强需求的场景(如金融系统),优先考虑 Session。微服务架构、移动端、跨域 API 场景,JWT 更合适。实际生产常采用“JWT + 短过期 + Refresh Token”的混合方案。
1.4 核心声明字段
JWT Payload 中的声明分为三类:注册声明(Registered Claims)、公共声明(Public Claims)和私有声明(Private Claims)。以下为最常用的注册声明:
| 声明 | 全称 | 说明 | 是否必选 |
|---|---|---|---|
iss |
Issuer | 签发者,标识令牌的发行方 | 推荐 |
sub |
Subject | 主题,通常为用户 ID | 推荐 |
aud |
Audience | 接收方,标识令牌的目标服务 | 可选 |
exp |
Expiration Time | 过期时间(Unix 时间戳),过期后令牌无效 | 必选 |
nbf |
Not Before | 生效时间,在此之前令牌不可用 | 可选 |
iat |
Issued At | 签发时间 | 推荐 |
jti |
JWT ID | 令牌唯一标识,用于防重放 | 可选 |