JWT认证授权契约校验 - 第1节
1.1 什么是JWT
JWT(JSON Web Token)是一种基于 JSON 格式的开放标准(RFC 7519),用于在各方之间以紧凑、自包含的方式安全传输信息。JWT 通常用于身份认证和信息交换场景,其核心特点是:自包含(所有必要信息都在 Token 内部)和可验证(通过数字签名确保数据未被篡改)。
JWT 的本质:一种紧凑的、URL 安全的、自包含的声明传递方式,使用 JSON 格式编码,并通过 HMAC 或 RSA/ECDSA 进行签名或加密。
JWT 的结构
一个完整的 JWT 由三部分组成,以点号(.)分隔:
Header.Payload.Signature
| 部分 | 说明 | 示例(解码后) |
|---|---|---|
| Header(头部) | 包含 Token 类型(typ)和签名算法(alg),如 HS256、RS256 | {"alg":"HS256","typ":"JWT"} |
| Payload(载荷) | 包含声明(claims),如用户 ID、角色、过期时间等业务数据 | {"sub":"1234567890","name":"张三","iat":1516239022} |
| Signature(签名) | 对 Header 和 Payload 进行签名,防止数据被篡改 | HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) |
注意:Payload 中的信息是 Base64Url 编码,并非加密。敏感数据(如密码)不应直接放入 JWT 的 Payload 中。
1.2 JWT 与 Session/Cookie 的区别
传统的 Session/Cookie 认证方式与 JWT 认证方式在架构、存储和扩展性上存在本质差异。下表从多个维度进行对比:
| 对比维度 | Session / Cookie | JWT |
|---|---|---|
| 存储位置 | Session 数据存储在服务器端(内存/数据库),Cookie 存储在客户端 | Token 完全存储在客户端(浏览器 LocalStorage / 移动端内存) |
| 服务器状态 | 有状态(服务器必须保存 Session 信息) | 无状态(服务器不保存 Token 信息,仅验证签名) |
| 扩展性 | 水平扩展困难,需要 Session 共享(如 Redis 集中存储) | 天然支持水平扩展,任何服务器均可独立验证 |
| 跨域支持 | 受同源策略限制,跨域需额外配置(CORS + 凭证) | 天然支持跨域,Token 通过 HTTP Header 传递 |
| 安全性 | 依赖 Cookie 的 HttpOnly / Secure 属性,防 XSS 较好 | 需防范 XSS(Token 被窃取),建议配合 HTTPS 和短有效期 |
| 性能 | 每次请求需查询 Session 存储(I/O 开销) | 仅需本地计算验证签名(CPU 开销),无 I/O 延迟 |
| Token 失效 | 服务器可主动删除 Session,立即失效 | Token 签发后无法主动失效,需等待过期或维护黑名单 |
关键决策点:如果系统需要服务器主动控制会话失效(如强制下线、账号封禁),Session 方案更直接;如果系统追求无状态、高扩展性和跨域能力,JWT 是更优选择。
1.3 JWT 的典型应用场景
JWT 因其无状态、跨域友好和自包含的特性,在以下场景中得到广泛应用:
- 单点登录(SSO):JWT 是 SSO 系统的首选方案。用户在一个系统登录后,生成的 JWT 可在多个子系统间共享,无需重复登录。
- 移动端 API 认证:移动端(iOS/Android)没有 Cookie 机制,JWT 通过 HTTP Header 传递,天然适配移动端无状态请求。
- 微服务间认证:在微服务架构中,服务间调用使用 JWT 传递用户身份和权限信息,避免每次调用都查询集中式 Session。
- 第三方 API 授权:开放平台使用 JWT 作为 Access Token,第三方应用携带 JWT 调用 API,平台验证签名即可确认身份。
- 信息交换:JWT 的签名机制确保数据在传输过程中未被篡改,适合在不可信环境中交换声明信息。
实战建议:在微服务架构中,建议将 JWT 的有效期设置为 15-30 分钟,配合 Refresh Token 机制实现长期登录,同时降低 Token 泄露风险。
JWT 认证流程(标准模式)
- 用户使用用户名/密码登录客户端。
- 客户端将凭证发送至认证服务器。
- 认证服务器验证凭证,生成 JWT(包含用户 ID、角色、过期时间等声明)。
- 客户端收到 JWT 并存储在本地(LocalStorage / 内存)。
- 客户端在后续请求的 HTTP Header 中携带 JWT(格式:
Authorization: Bearer <token>)。 - 资源服务器验证 JWT 签名和有效期,提取用户信息,处理请求。
- JWT 过期后,客户端使用 Refresh Token 获取新的 Access Token。
JWT 的声明类型
JWT 的 Payload 中包含三类声明(Claims),每类声明有不同的用途和约束:
| 声明类型 | 说明 | 常见声明 |
|---|---|---|
| 注册声明(Registered Claims) | JWT 标准预定义的声明,提供互操作性 | iss(签发者)、sub(主题)、aud(受众)、exp(过期时间)、iat(签发时间) |
| 公共声明(Public Claims) | 由使用方自定义,需在 IANA 注册或使用 URI 避免冲突 | https://api.example.com/role(自定义角色声明) |
| 私有声明(Private Claims) | 双方协商使用的自定义声明,不要求全局唯一 | user_id、department、permissions |
最佳实践:始终在 JWT 中包含
exp(过期时间)和 iat(签发时间)声明。过期时间建议设置为 15-30 分钟,避免 Token 长期有效带来的安全风险。