2. JWT 结构详解:Header、Payload、Signature 的组成与作用

JSON Web Token(JWT)是一种紧凑的、URL 安全的令牌表示方式,用于在各方之间以 JSON 对象的形式安全地传输信息。一个标准的 JWT 由三个独立的部分组成,它们通过点号(.)连接,形成如下格式:

xxxxx.yyyyy.zzzzz

这三部分分别对应 Header(头部)、Payload(载荷) 和 Signature(签名)。每一部分都经过 Base64URL 编码,确保在 HTTP 头或 URL 参数中传输时不会产生歧义。

关键认知:JWT 的每一部分都是独立编码的,但只有 Signature 部分能保证令牌的完整性和真实性。Header 和 Payload 仅经过编码(非加密),因此不应在其中存放敏感信息(如密码、信用卡号)。
JWT 三段式结构分解 JWT 三段式结构:Header.Payload.Signature Header 头部(元数据 + 算法) Payload 载荷(声明数据) Signature 签名(防篡改) 最终格式:Base64URL(Header).Base64URL(Payload).Base64URL(Signature)

2.1 Header(头部)

Header 是 JWT 的第一部分,通常包含两个主要字段:令牌类型(typ)和签名算法(alg)。它描述了如何对 JWT 进行签名或加密处理。

字段 含义 示例值 说明
alg 签名算法 HS256 / RS256 必填。指定生成 Signature 的算法。HS256 为对称 HMAC-SHA256,RS256 为非对称 RSA-SHA256。
typ 令牌类型 JWT 可选。通常固定为 JWT,表示这是一个 JWT 令牌。
kid 密钥 ID key-abc-123 可选。当使用多组密钥时,用于标识具体使用哪一组密钥进行验证。

一个典型的 Header JSON 对象如下:

{
  "alg": "HS256",
  "typ": "JWT"
}

该 JSON 经过 Base64URL 编码后,形成 JWT 的第一段字符串。

安全警告:切勿使用 alg: "none"。某些旧版 JWT 库允许将算法设为 none 以跳过签名验证,这会导致严重的安全漏洞,攻击者可以伪造任意令牌。生产环境中必须禁用 none 算法。

2.2 Payload(载荷)

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

类型 说明 常见字段
注册声明 预定义的一组非强制性但推荐的声明,提供互操作性。 iss(签发者)、sub(主题)、aud(受众)、exp(过期时间)、nbf(生效时间)、iat(签发时间)、jti(JWT ID)
公共声明 由使用 JWT 的各方自行定义,为避免冲突,建议在 IANA JSON Web Token Claims 注册表中注册,或使用命名空间 URI。 name、preferred_username
私有声明 在同意使用 JWT 的各方之间共享的自定义声明,不属于注册或公共声明。 user_id、role、permissions

一个典型的 Payload JSON 对象示例:

{
  "sub": "1234567890",
  "name": "张三",
  "iat": 1516239022,
  "exp": 1516242622,
  "role": "admin",
  "permissions": ["read:users", "write:users"]
}
最佳实践:Payload 中只存放必要的最小声明集。避免存放敏感数据,因为 Payload 仅经过 Base64URL 编码,任何人都可以解码读取。对于需要保密的信息,应使用 JWE(JSON Web Encryption)进行加密。

2.3 Signature(签名)

Signature 是 JWT 的第三部分,用于验证消息在传输过程中未被篡改,并确认消息的发送方身份。签名的生成过程依赖于 Header 中指定的算法和一个密钥(或密钥对)。

签名生成的基本公式如下:

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

具体步骤:

  1. 将 Header 和 Payload 分别进行 Base64URL 编码。
  2. 将编码后的 Header 和 Payload 用点号(.)连接起来。
  3. 使用 Header 中指定的算法(如 HMAC-SHA256)和密钥对上述字符串进行签名。
  4. 将生成的签名进行 Base64URL 编码,得到 Signature 部分。

验证方收到 JWT 后,使用相同的算法和密钥重新计算签名,并与 JWT 中的 Signature 进行比较。如果一致,则证明令牌未被篡改且来源可信。

JWT 签名生成与验证流程 JWT 签名生成与验证流程 签名生成(服务端) Base64URL(Header) Base64URL(Payload) 拼接:Header.Payload HMACSHA256(数据, 密钥) 签名验证(服务端) Base64URL(Header) Base64URL(Payload) 拼接:Header.Payload 比较签名是否一致

2.4 三部分协同工作

JWT 的三个部分各司其职,共同构建了一个安全、自包含的令牌系统:

  • Header 告诉验证方“我是如何被签名的”,确保双方使用相同的算法规则。
  • Payload 携带业务数据,如用户 ID、角色、过期时间等,使令牌具有自描述能力。
  • Signature 提供完整性保护和身份认证,防止数据被篡改,并确保令牌来自持有密钥的合法签发方。

在分布式系统中,这种结构使得服务无需查询中心化的会话存储,仅通过验证 JWT 签名即可确认用户身份和权限,从而实现无状态鉴权。

核心结论:JWT 的结构设计体现了“信任但验证”的安全原则。Header 和 Payload 是公开可读的,但 Signature 确保了它们的完整性和真实性。在分布式鉴权场景中,正确实现签名验证是保障系统安全的第一道防线。