2、JWT结构解析:Header头部、Payload载荷、Signature签名的组成与作用

JWT(JSON Web Token)是一种紧凑的、URL安全的令牌表示方式,其核心结构由三个独立的部分通过点号(.)连接而成。理解这三部分的组成与作用,是进行JWT契约校验的基础。

JWT标准结构示例:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

上述令牌由三个Base64URL编码的字符串组成,分别对应Header、Payload和Signature。

JWT 三段式结构全景图 Header(头部) 算法 & 令牌类型 {"alg":"HS256","typ":"JWT"} Base64URL 编码 . Payload(载荷) 声明(Claims)数据 {"sub":"123","name":"John"} Base64URL 编码 . Signature(签名) 数据完整性验证 HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) 最终JWT格式:Header.Payload.Signature(三段由点号连接)

2.1 Header(头部)—— 算法与类型声明

Header是JWT的第一段,通常包含两个关键字段:令牌类型(typ)和签名算法(alg)。它告诉接收方如何解析和验证这个令牌。

字段 含义 常见值 说明
alg 签名算法(Algorithm) HS256、RS256、ES256 必填字段,指定用于生成签名的算法
typ 令牌类型(Type) JWT 可选字段,通常固定为"JWT"
cty 内容类型(Content Type) JWT 可选字段,用于嵌套签名或加密场景
安全提示:alg字段是JWT安全的关键。服务端在校验时必须严格限制允许的算法列表,防止攻击者将"RS256"篡改为"none"或对称算法"HS256"来绕过签名验证。
// 典型的JWT Header示例
{
  "alg": "HS256",   // 使用HMAC-SHA256对称签名算法
  "typ": "JWT"      // 声明这是一个JWT令牌
}

2.2 Payload(载荷)—— 声明数据的载体

Payload是JWT的第二段,包含实际传递的声明(Claims)。声明是关于实体(通常是用户)和附加元数据的陈述。JWT规范定义了三种类型的声明:注册声明、公共声明和私有声明。

2.2.1 注册声明(Registered Claims)

这些是预定义的、非强制性的但推荐使用的声明,提供一组有用的、可互操作的声明名称。

声明名 全称 说明 校验要点
iss Issuer 签发者,标识签发JWT的主体 验证是否与预期签发者匹配
sub Subject 主题,标识JWT所面向的用户 通常为用户的唯一标识
aud Audience 接收方,标识JWT的预期接收者 验证当前服务是否在aud列表中
exp Expiration Time 过期时间,UNIX时间戳格式 必须校验当前时间是否已超过exp
nbf Not Before 生效时间,在此之前JWT不可用 当前时间必须晚于nbf
iat Issued At 签发时间,UNIX时间戳格式 可用于判断令牌是否过于陈旧
jti JWT ID 唯一标识符,防止重放攻击 服务端需维护已使用的jti列表

2.2.2 公共声明与私有声明

  • 公共声明(Public Claims):在IANA JSON Web Token Claims注册表中定义的声明,或使用URI(统一资源标识符)作为名称以避免冲突。
  • 私有声明(Private Claims):由JWT的生产者和消费者之间协商的自定义声明,如角色、权限、用户昵称等业务数据。
// 一个包含多种声明的Payload示例
{
  "iss": "https://auth.example.com",   // 注册声明:签发者
  "sub": "user_123456",                // 注册声明:用户ID
  "aud": ["api.example.com"],          // 注册声明:接收方
  "exp": 1735689600,                   // 注册声明:过期时间
  "iat": 1735603200,                   // 注册声明:签发时间
  "role": "admin",                     // 私有声明:用户角色
  "permissions": ["read", "write"]     // 私有声明:权限列表
}
重要提醒:Payload仅经过Base64URL编码,并未加密。任何持有令牌的人都可以解码并读取其中的内容。切勿在Payload中存放密码、密钥、信用卡号等敏感信息。如需保护数据内容,应使用JWE(JSON Web Encryption)。

2.3 Signature(签名)—— 完整性与真实性的保障

Signature是JWT的第三段,通过对Header和Payload进行签名生成,用于验证令牌在传输过程中未被篡改,并确认其确实由预期的签发者生成。

签名的生成过程如下:

  1. 将Header和Payload分别进行Base64URL编码。
  2. 将编码后的Header和Payload用点号(.)连接,形成签名输入字符串。
  3. 使用Header中指定的算法(alg)和密钥(secret或私钥)对输入字符串进行签名。
  4. 将生成的签名进行Base64URL编码,作为JWT的第三段。
// 签名生成伪代码(以HMAC-SHA256为例)
signature = HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret_key
)
Signature 签名生成与验证流程 签名生成(服务端) Base64URL(Header) Base64URL(Payload) Header + "." + Payload 密钥 (Secret) 算法 (HS256) Signature 签名验证(接收端) Base64URL(Header) Base64URL(Payload) Header + "." + Payload 相同密钥 相同算法 新签名 比较

2.4 三段结构的协同作用

JWT的三段结构各自承担不同职责,共同保障令牌的安全传输:

组成部分 核心职责 是否加密 是否可篡改 校验重点
Header 声明解析方式与算法 否(仅编码) 可篡改,但会被签名检测 验证alg是否在白名单内
Payload 承载业务数据与元数据 否(仅编码) 可篡改,但会被签名检测 验证exp、nbf、aud等声明
Signature 保证完整性与真实性 是(签名不可逆) 不可篡改(无密钥无法伪造) 重新计算签名并比对
核心结论:JWT的安全性建立在Signature之上。Header和Payload虽然可读,但任何修改都会导致签名验证失败。在契约校验中,签名验证是第一步,也是最重要的一步——只有通过签名验证的令牌,才值得进一步检查Payload中的声明内容。