JWT的组成

前言

本文谈谈 【JWT 的组成部分】 目标是看完之后,需要能用自己的语言说出【JWT 由哪几部分构成,各部分的作用是什么】

正文

JWT(JSON Web Token) 是一种开放标准(RFC 7519),它定义了一种 紧凑的(Compact)自包含的(Self-contained) 方式,用于在各方之间安全地传输信息作为 JSON 对象。

这些信息可以被 验证信任 ,由于它是 数字签名 的。JWT 可以使用 密钥(HMAC 算法) 或使用 RSA 或 ECDSA 的公钥/私钥对 进行签名。

一个 JWT 实际上就是一个字符串,它由三部分组成,用点(.)分隔开,格式如下:

header.payload.signature #技术分享

也就是:

xxxxx.yyyyy.zzzzz

这三部分分别是:

  1. Header (头部)
  2. Payload (有效载荷)
  3. Signature (签名)

下面我们来详细拆解每一部分。


1. Header (头部)

作用 :描述 JWT 的 元数据(Metadata) ,最主要的是声明 签名算法令牌类型

  • 典型内容
  • alg (algorithm): 签名使用的算法 。例如 HS256 (HMAC SHA-256) 或 RS256 (RSA SHA-256)。
  • typ (type): 令牌类型 。一般就是 JWT
  • 数据处理流程
  • 这个 JSON 对象会通过 Base64Url 编码(一种针对 URL 安全的 Base64 编码),形成 JWT 的 第一部分

示例

一个原始的 Header JSON:

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

经过 Base64Url 编码后,得到 JWT 的第一部分:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

小提示!!!:Base64 是一种编码方式, 不是加密 !!!所以 Header 部分的内容任何人都可以解码看到。你可以直接把上面的编码字符串拿去任何在线 Base64 解码工具解码,就能还原出原始的 JSON。


2. Payload (有效载荷)

作用 :携带实际的 声明(Claims) 。声明就是关于实体(一般是用户)和其他数据的语句。

  • 声明类型
  • 注册声明(Registered Claims) :预定义的一组标准声明,非强制但推荐使用,用于提供一组有用的、可互操作的声明。
  • iss (issuer): 签发者
  • sub (subject): 主题 (一般是用户 ID)。
  • aud (audience): 接收方
  • exp (expiration time): 过期时间 (Unix 时间戳)。
  • nbf (not before): 生效时间 ,在此时间之前令牌无效。
  • iat (issued at): 签发时间
  • 公共声明(Public Claims) :可以随意定义的声明,但为了避免冲突,应该在 IANA JSON Web Token Registry 中定义它们,或者使用一个防冲突的命名空间(如包含域名)。
  • 私有声明(Private Claims) :在提供者和消费者之间 共同约定 的、用于共享信息的自定义声明,既不是注册声明也不是公共声明。
  • 例如: username , role 等。
  • 数据处理流程
  • Payload 的 JSON 对象同样会通过 Base64Url 编码,形成 JWT 的 第二部分

示例

一个原始的 Payload JSON:

{
    "sub": "1234567890",
    "name": "John Doe",
    "iat": 1516239022,
    "admin": true
}

经过 Base64Url 编码后,得到 JWT 的第二部分:
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJhZG1pbiI6dHJ1ZX0

⚠️ 重大提醒 :和 Header 一样,Payload 也 仅仅是 Base64Url 编码 ,【并非加密】!!!。 绝对不要在 JWT 的 Payload 或 Header 中放置敏感信息 (如密码),除非整个 JWT 被额外加密了(参见 JWE)。


3. Signature (签名)

作用 :这是 JWT 的 安全核心 。用于 验证消息在传输过程中没有被篡改 ,并且对于使用私钥签名的令牌,它还可以验证发送方的身份。

  • 生成方式
  • 编码后的 Header编码后的 Payload ,用一个点(.)连接起来,形成一个字符串: base64UrlEncode(header) + “.” + base64UrlEncode(payload)
  • 使用在 Header 中指定的签名算法(如 HS256 ),和一个 密钥(Secret)私钥(Private Key) ,对这个连接起来的字符串进行 签名

以 HS256 为例的签名公式

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

然后将签名结果(一个二进制哈希值)也进行 Base64Url 编码,形成 JWT 的 第三部分

示例

假设我们的密钥是字符串 “your-256-bit-secret”。对
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJhZG1pbiI6dHJ1ZX0
进行 HMAC-SHA256 签名并编码后,得到第三部分:
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

核心价值 :签名是关键!即使 Header 和 Payload 可以被任何人解码查看,但 无法被篡改 。由于服务器在收到 JWT 后,会用同样的密钥和算法重新计算前两部分的签名,如果计算结果与第三部分不匹配,就说明令牌被篡改了,应立即拒绝。


最终的 JWT

将上面三个用点分隔的 Base64Url 字符串拼接起来,就形成了一个完整的 JWT:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJhZG1pbiI6dHJ1ZX0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

我们可以用一个简单的流程图来回顾 JWT 的生成过程:

【生成 JWT】
┌─────────────────┐    ┌──────────────────┐    ┌──────────────────┐
│  1.

│ │ │ │ │ │ │ { │ │ { │ │ 取前两部分编码结果:│ │ "alg": "HS256",│ │ "sub": "123...", │ │ header_b64 +

│ "typ": "JWT" │ │ "name": "Jo...", │ │ +

│ } │ │ ... │ │ │ │ │ │ } │ │ 用密钥(Secret) │ └─────────────────┘ └──────────────────┘ │ 和 Header 中指定 │ | | │ 的算法(alg)进行 │ ↓ (Base64Url 编码) ↓ (Base64Url 编码)│ 签名(HMAC 等) │ ┌─────────────────┐ ┌──────────────────┐ │ │ │ header_b64 │ │ payload_b64 │ │ 得到签名后同样 │ │ "eyJhbGc..." │ │ "eyJzdWI..." │ │ 进行 Base64Url 编码│ └─────────────────┘ └──────────────────┘ │ │ _________________________/ └──────────────────┘ | | ↓ (用点 . 连接) ↓ (编码后) header_b64 + "." + payload_b64 signature_b64 _________________________ ________________/ | ↓ (最终用点 . 连接) 最终 JWT = header_b64 + "." + payload_b64 + "." + signature_b64

验证 JWT 时,服务端会做反向操作

  1. 将 JWT 按点分割成三部分。
  2. 用一样的密钥和算法,对前两部分重新计算签名。
  3. 将自己计算的签名与 JWT 自带的第三部分签名进行 安全的比对 (防止计时攻击)。
  4. 如果签名一致,则证明令牌有效且未被篡改;同时,可以解码 Payload 提取其中的信息(如用户 ID、权限等)。

最后

我们来回答开头的问题:JWT 由哪几部分构成,各部分的作用是什么?

JWT 由三部分组成,用点(.)分隔:

  1. Header(头部) :经过 Base64Url 编码的 JSON 对象,主要声明签名算法(alg)和令牌类型(typ)。
  2. Payload(有效载荷) :经过 Base64Url 编码的 JSON 对象,携带了实际的声明(Claims),如用户身份(sub)、过期时间(exp)等自定义信息。
  3. Signature(签名) :对前两部分连接后的字符串,通过指定的算法和密钥进行签名并编码的结果,是验证令牌完整性和真实性的核心。

核心要点 :Header 和 Payload 仅是编码,不加密 ,切勿存放敏感信息。JWT 的安全性完全依赖于签名。

相关链接

  • JWT 官方介绍
  • RFC 7519 – JSON Web Token (JWT)
© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容