摘要:JWT(JSON Web Token)是一种开放标准(RFC 7519),它定义了一种紧凑的(Compact)、自包含的(Self-contained)方式,用于在各方之间安全地传输信息作为 JSON 对象。
本文谈谈 【JWT 的组成部分】 目标是看完之后,需要能用自己的语言说出【JWT 由哪几部分构成,各部分的作用是什么】
JWT(JSON Web Token) 是一种开放标准(RFC 7519),它定义了一种 紧凑的(Compact) 、自包含的(Self-contained) 方式,用于在各方之间安全地传输信息作为 JSON 对象。
这些信息可以被 验证 和 信任 ,因为它是 数字签名 的。JWT 可以使用 密钥(HMAC 算法) 或使用 RSA 或 ECDSA 的公钥/私钥对 进行签名。
一个 JWT 实际上就是一个字符串,它由三部分组成,用点(.)分隔开,格式如下:
header.payload.signature #技术分享也就是:
xxxxx.yyyyy.zzzzz这三部分分别是:
Header (头部)Payload (有效载荷)Signature (签名)下面我们来详细拆解每一部分。
作用 :描述 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。
作用 :携带实际的 声明(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)。
作用 :这是 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 时,服务端会做反向操作 :
将 JWT 按点分割成三部分。用相同的密钥和算法,对前两部分重新计算签名。将自己计算的签名与 JWT 自带的第三部分签名进行 安全的比对 (防止计时攻击)。如果签名一致,则证明令牌有效且未被篡改;同时,可以解码 Payload 提取其中的信息(如用户 ID、权限等)。我们来回答开头的问题:JWT 由哪几部分构成,各部分的作用是什么?
JWT 由三部分组成,用点(.)分隔:
Header(头部) :经过 Base64Url 编码的 JSON 对象,主要声明签名算法(alg)和令牌类型(typ)。Payload(有效载荷) :经过 Base64Url 编码的 JSON 对象,携带了实际的声明(Claims),如用户身份(sub)、过期时间(exp)等自定义信息。Signature(签名) :对前两部分连接后的字符串,通过指定的算法和密钥进行签名并编码的结果,是验证令牌完整性和真实性的核心。核心要点 :Header 和 Payload 仅是编码,不加密 ,切勿存放敏感信息。JWT 的安全性完全依赖于签名。
来源:墨码行者