JSON Web Token
JSON Web Token (JWT) 是一套定义了多方之间使用 JSON 对象传输信息的标准( RFC 7519 ),适用于鉴权和交换信息。
JWT 包含 3 部分:
-
Header:一个 JSON 对象的 Base64Url 编码格式,该 JSON 对象通常包含 token 类型和签名算法两部分。
- 签名算法包括 HMAC,RSA,ECDSA。
{ "alg": "HS256", "typ": "JWT" }
-
Payload:一个 JSON 对象的 Base64Url 编码格式,由若干数据的描述信息(claim)组成。
- claim 可以分为 3 类:
- 标准中
预定义的 claim
:如
iss
(issuer),exp
(expiration time),sub
(subject) 等,便于互操作,推荐使用。为了保持紧凑,此类 claim 名称都是 3 个字符。 - 公开的 claim:可以直接从 IANA JSON Web Token Registry 中选择注册过 claim 来使用,这样可以避免随便定义新的 claim 名导致和已有的名称冲突。
- 隐私的 claim:JWT 的生产者和消费者之间自行约定,可能与上面两种类型的 claim 冲突。
- 标准中
预定义的 claim
:如
- 未经加密处理的 Payload 中的用户信息直接解码就能获得(因此不应该包含敏感信息),减少了数据库查询操作的次数。
{ "sub": "1234567890", "name": "John Doe" }
- claim 可以分为 3 类:
-
Signature:用于校验 JWT 包含的信息是否被篡改过。
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
JWT 的 3 部分之间用 .
分隔,拼接成一个字符串。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
JWT 在鉴权场景中的使用流程:
-
用户在客户端登录成功;
-
服务端生成 JWT 返回给客户端;
-
后续客户端访问受保护的路由和资源时,请求中都要带上 JWT。
# JWT 通常放在 HTTP header 中,格式如下 Authorization: Bearer <token>
JWT 的优点:
-
JSON 格式简洁易读,编码后体积小,解码操作在很多编程语言中都可以很方便地进行;
-
支持多种签名算法;
-
服务端无需维护 token 信息。
-
Base64:将二进制编码成文本的规则。
- 字符集:
A-Z
,a-z
,0-9
,+
,/
,分别对应编号 0-63(2^6)。 - 编码:
- 每 3 个字节(24 bit)划成一组,不足 3 个字节则补 0 凑足 3 字节;
- 每 3 个字节(24 bit)分成 4 组(每组 6 bit),每组前面补上
00
凑成 1 字节,这样 24 bit 就扩展成 32 bit(4 字节,值的范围 0-63); - 将每个字节映射到字符集中相应编号对应的字符。
- 若原字符需要补一个字节的
0
,则编码后的最后一个字符要覆盖为=
;若原字符需要补两个字节的0
,则编码后的最后两个字符要覆盖为=
。
- 若原字符需要补一个字节的
- Base64URL 基于 Base64 做了一些改动(替换特殊字符,没有补位),目的是使编码的结果可以用作文件名或 URL。
- 字符集:
References