3. JSON Web 令牌 (JWT) 概述
JWT 将一组声明表示为 JSON 对象, 并将该对象编码在 JWS 和/或 JWE 结构中. 这个 JSON 对象就是 JWT 声明集 (JWT Claims Set). 按 RFC 7159 [RFC7159] 第 4 节, JSON 对象由零个或多个名称/值对 (或成员) 组成, 名称为字符串, 值为任意 JSON 值. 这些成员就是 JWT 所表示的声明. 按 RFC 7159 [RFC7159] 第 2 节, 该 JSON 对象可以在任意 JSON 值或结构字符之前或之后包含空白和/或换行 (MAY).
JWT 声明集中的成员名称称为声明名称 (Claim Names). 对应的值称为声明值 (Claim Values).
JOSE 头部 (JOSE Header) 的内容描述应用于 JWT 声明集的密码学操作. 如果 JOSE 头部对应 JWS, 则 JWT 表示为 JWS, 声明被数字签名或使用 MAC 保护, JWT 声明集作为 JWS 载荷. 如果 JOSE 头部对应 JWE, 则 JWT 表示为 JWE, 声明被加密, JWT 声明集作为 JWE 所加密的明文. JWT 可以被封装在另一个 JWE 或 JWS 结构中以创建嵌套 JWT (Nested JWT), 从而执行嵌套签名和加密.
JWT 表示为由句点 ('.') 字符分隔的一系列 URL 安全部分. 每一部分都包含一个 base64url 编码值. JWT 中的部分数量取决于最终 JWS 使用 JWS 紧凑序列化表示, 还是最终 JWE 使用 JWE 紧凑序列化表示.
3.1. JWT 示例 (Example JWT)
下面的 JOSE 头部示例声明被编码对象是 JWT, 并且该 JWT 是使用 HMAC SHA-256 算法进行 MAC 保护的 JWS:
{"typ":"JWT",
"alg":"HS256"}
为消除上述 JSON 对象表示中可能存在的歧义, 下面也给出本示例中该 JOSE 头部实际使用的 UTF-8 表示. 注意, 歧义可能来自不同平台对换行的表示不同 (CRLF 与 LF), 行首和行尾空格不同, 最后一行是否有终止换行不同, 以及其他原因. 在本示例使用的表示中, 第一行没有前导或尾随空格, 第一行和第二行之间有 CRLF 换行 (13, 10), 第二行有一个前导空格 (32) 且没有尾随空格, 最后一行没有终止换行. 本示例中 JOSE 头部的 UTF-8 表示如下 (使用 JSON 数组记法):
[123, 34, 116, 121, 112, 34, 58, 34, 74, 87, 84, 34, 44, 13, 10, 32,
34, 97, 108, 103, 34, 58, 34, 72, 83, 50, 53, 54, 34, 125]
对 JOSE 头部 UTF-8 表示的字节进行 Base64url 编码, 得到以下编码后的 JOSE 头部值:
eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9
下面是一个 JWT 声明集示例:
{"iss":"joe",
"exp":1300819380,
"http://example.com/is_root":true}
下面的字节序列是本示例中上述 JWT 声明集所使用的 UTF-8 表示, 也是 JWS 载荷:
[123, 34, 105, 115, 115, 34, 58, 34, 106, 111, 101, 34, 44, 13, 10,
32, 34, 101, 120, 112, 34, 58, 49, 51, 48, 48, 56, 49, 57, 51, 56,
48, 44, 13, 10, 32, 34, 104, 116, 116, 112, 58, 47, 47, 101, 120, 97,
109, 112, 108, 101, 46, 99, 111, 109, 47, 105, 115, 95, 114, 111,
111, 116, 34, 58, 116, 114, 117, 101, 125]
对 JWS 载荷进行 Base64url 编码, 得到以下编码后的 JWS 载荷 (换行仅用于显示):
eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly
9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ
使用 HMAC SHA-256 算法计算编码后的 JOSE 头部和编码后的 JWS 载荷的 MAC, 并按 [JWS] 规定的方式对 HMAC 值进行 base64url 编码, 得到以下编码后的 JWS 签名:
dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
按此顺序将这些编码部分用句点 ('.') 字符连接, 得到完整 JWT (换行仅用于显示):
eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9
.
eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFt
cGxlLmNvbS9pc19yb290Ijp0cnVlfQ
.
dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
该计算过程在 [JWS] 的 Appendix A.1 中有更详细说明. 有关加密 JWT 的示例, 请参见 Appendix A.1.