JSON Web Token (JWT)

7/26/2024 1:41:05 PM
159
0

简单总结来说,JWT是一个定义一种紧凑的自包含的并且提供防篡改机制的传递数据的方式的标准协议。

我们先来看一个简单的示例 :

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Imxpbmlhbmh1aSJ9.hnOfZb95jFwQsYj3qlgFbUu1rKpfTE6AzgXZidEGGTk

就是这么一堆看起来像是乱码一样的字符串。JWT由3部分构成 : header.payload.signature,每个部分由.来分割开来。

4.1 Header

header是一个有效的JSON,其中通常包含了两部分 : token类型和签名算法。

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

对这个JSON采用base64编码后就是第1部分

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

4.2 Payload

这一部分代表真正想要传递的数据,包含一组Claims,其中JWT预定义了一些Claim(RFC7662 OAuth2 Token Introspection)这一节就用到一些JWT预定义的一些Cliam)后面会介绍。关于什么是Claim,可以参考文章末尾给的参考链接。

{
  "sub": "1234567890",
  "name": "linianhui"
}

对这个JSON采用base64编码后就是第2部分

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Imxpbmlhbmh1aSJ9

4.3 Signature

这一部分是可选的,由于前面Header和Payload部分是明文的信息,所以这一部分的意义在于保障信息不被篡改用的,生成这部分的方式如下 :

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

token生成方使用header中指定的签名算法对header.payload部分进行签名,得到的第3部分hnOfZb95jFwQsYj3qlgFbUu1rKpfTE6AzgXZidEGGTk,然后组合成一个完整的JWT字符串 . 而token消费方在拿到token后, 使用同样的签名算法来生成签名,用来判断headerpayload部分有没有被篡改过,因为签名的密钥是只有通信双方知道的,所以可以保证这部分信息不被第三方所篡改。

4.4 JWT Claims

JWT规范中预先定义了一些Cliam,但并不是必选的,常用的有 :

  1. iss : Issuer 签发者。
  2. sub : subject签发给的受众,在Issuer范围内是唯一的。
  3. aud : Audience接收方。
  4. exp : Expiration Time过期时间。
  5. iat : Issued At签发时间 等等。

更完整的一些Claim列表参见 : https://www.iana.org/assignments/jwt/jwt.xhtml

如果上面这些仍无法满足自己的需要,则可以自定义一些来使用。

4.5 JWT 应用场景

由于其采用base64来进行编码,使得它可以安全的用在一些仅限_ASCII_的地方传递信息,比如URL的querystring中。

比如用户登陆后,可以把用户的一些属性信息(用户标识,是否是管理员,权限有哪些等等可以公开的信息)用JWT编码存储在cookie中,由于其自包含的性质,每次服务器读取到Cookie的时候就可以解析到当前用户对应的属性信息,而不必再次去查询数据库。如果Cookie中每次都发送浪费带宽,也可以用Authorization: Bearer jwttoken 的方式附加到Http Request上去。

全部评论



提问