3. JWT核心概念

3.1 JWT定义

JWT(JSON Web Token) 是一种基于 JSON 的开放标准(RFC 7519),用于在各方之间以紧凑且自包含的方式安全地传输信息。JWT 通常用于身份认证和信息交换场景,其核心特点是:

  • 紧凑(Compact):JWT 体积小,可通过 URL、POST 参数或 HTTP Header 快速传输。
  • 自包含(Self-contained):JWT 本身携带了用户身份、权限等声明信息,无需频繁查询数据库。
  • 防篡改(Tamper-proof):JWT 通过签名机制保证内容在传输过程中未被篡改。
💡 关键理解: JWT 不是加密数据,而是对数据进行签名。签名确保数据来源可信且未被篡改,但 JWT 的 Payload 默认是 Base64URL 编码,并非加密。敏感信息不应直接放入 JWT 的 Payload。

3.2 JWT结构

一个完整的 JWT 由三个部分组成,以点号(.)分隔:

xxxxx.yyyyy.zzzzz
│     │     │
│     │     └── Signature(签名)
│     └──────── Payload(载荷)
└───────────── Header(头部)

3.2.1 Header(头部)

Header 通常包含两部分信息:令牌类型(typ)和签名算法(alg)。

{
  "alg": "HS256",
  "typ": "JWT"
}
字段 含义 常见值
alg 签名算法 HS256(HMAC-SHA256)、RS256(RSA-SHA256)
typ 令牌类型 JWT
kid 密钥标识(可选) 用于多密钥场景

3.2.2 Payload(载荷)

Payload 是 JWT 的主体,包含声明(Claims)。声明分为三类:

  • 注册声明(Registered Claims):预定义的标准字段,如 iss(签发者)、sub(主题)、exp(过期时间)、iat(签发时间)。
  • 公共声明(Public Claims):自定义字段,需在 IANA JSON Web Token Registry 注册或使用防冲突命名。
  • 私有声明(Private Claims):双方约定的自定义字段,如 user_id、role。
{
  "sub": "1234567890",
  "name": "张三",
  "role": "admin",
  "iat": 1516239022,
  "exp": 1516242622
}
声明 全称 说明
iss Issuer 签发者
sub Subject 主题(通常为用户 ID)
aud Audience 接收方
exp Expiration Time 过期时间(UNIX 时间戳)
nbf Not Before 生效时间
iat Issued At 签发时间
jti JWT ID 唯一标识,防重放

3.2.3 Signature(签名)

Signature 是对 Header 和 Payload 的签名,用于验证消息在传输过程中未被篡改。生成过程如下:

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

签名使用 Header 中指定的算法(如 HS256)和密钥(secret)对前两部分进行加密。接收方使用相同的密钥和算法重新计算签名,比对是否一致。

⚠️ 安全警告: 签名密钥必须严格保密。如果密钥泄露,攻击者可以伪造任意 JWT。在生产环境中,建议使用环境变量或密钥管理服务存储密钥,切勿硬编码在代码中。

3.3 JWT工作原理

JWT 的工作流程分为签发、传输和验证三个阶段。下图展示了完整的交互过程:

JWT 工作原理流程图 客户端 (浏览器/移动端) 认证服务器 (签发与验证) ① 发送登录凭证 ② 验证凭证 生成 JWT ③ 返回 JWT 令牌 存储 JWT (LocalStorage/Cookie) ④ 携带 JWT 访问资源 资源服务器 (API 接口) ⑤ 验证签名与过期时间 ⑥ 返回受保护资源 JWT 验证过程 1. 解析 Header,获取签名算法 2. 使用密钥重新计算签名,比对是否一致 3. 检查 exp、nbf 等时间声明

3.4 JWT 验证流程详解

服务器在收到 JWT 后,按以下步骤进行验证:

  1. 解析令牌:以点号(.)分割 JWT,获取 Header、Payload 和 Signature。
  2. Base64URL 解码 Header:读取 alg 字段,确定签名算法。
  3. 重新计算签名:使用服务器密钥和指定算法,对 base64UrlEncode(header) + "." + base64UrlEncode(payload) 重新签名。
  4. 比对签名:将重新计算的签名与 JWT 中的 Signature 进行比对。一致则通过,否则拒绝。
  5. 验证声明:检查 exp(是否过期)、nbf(是否生效)、iss(签发者是否可信)等。
🔑 核心要点: JWT 的无状态特性使其非常适合分布式系统。服务器无需存储会话信息,只需验证签名即可确认用户身份。但这也意味着 JWT 一旦签发,在过期前无法主动撤销,因此 exp 的设置至关重要。

3.5 JWT 与 Session 对比

特性 JWT Session
存储位置 客户端(令牌自包含) 服务器(内存/数据库)
扩展性 天然支持分布式,无需共享存储 需要集中式 Session 存储(如 Redis)
撤销能力 无法主动撤销,需等待过期 可随时删除 Session
性能 验证快(仅计算签名) 需查询存储,高并发下可能成为瓶颈
安全性 签名防篡改,但 Payload 可读 数据存储在服务器,客户端仅持有 ID
⚠️ 常见误区: JWT 的 Payload 是 Base64URL 编码,不是加密。任何拥有令牌的人都可以解码查看内容。切勿在 Payload 中存放密码、信用卡号等敏感信息。如需加密,应使用 JWE(JSON Web Encryption)。