JWT

JSON Web Token (JWT):是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。          

        什么是 JWT

组成

JWT由三个部分组成:header.payload.signature

           组成

header部分:

1 {
2   "alg": "HS256",
3   "typ": "JWT"
4 }

对应base64UrlEncode编码为:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

说明:该字段为json格式。alg字段指定了生成signature的算法,默认值为 HS256,typ默认值为JWT

payload部分:

该部分包括:

  • 标准中注册的声明
  • 公共的声明
  • 私有的声明
1 {
2   "sub": "1234567890",
3   "name": "John Doe",
4   "iat": 1516239022
5 }

对应base64UrlEncode编码为:eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ

说明:该字段为json格式,表明用户身份的数据,可以自己自定义字段,很灵活。sub 面向的用户,name 姓名 ,iat 签发时间。例如可自定义示例如下:

1 {
2     "iss": "admin",          //该JWT的签发者
3     "iat": 1535967430,        //签发时间
4     "exp": 1535974630,        //过期时间
5     "nbf": 1535967430,         //该时间之前不接收处理该Token
6     "sub": "www.admin.com",   //面向的用户
7     "jti": "9f10e796726e332cec401c569969e13e"   //该Token唯一标识
8 }

signature部分:

1 HMACSHA256(
2   base64UrlEncode(header) + "." +
3   base64UrlEncode(payload),
4   123456
5 )

对应的签名为:keH6T3x1z7mmhKL1T3r9sQdAxxdzB6siemGMr_6ZOwU

最终得到的JWT的Token为(header.payload.signature):

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.keH6T3x1z7mmhKL1T3r9sQdAxxdzB6siemGMr_6ZOwU

说明:对header和payload进行base64UrlEncode编码后进行拼接。通过key(这里是123456)进行HS256算法签名。

有效载荷

有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。 JWT指定七个默认字段供选择。

iss:发行人

exp:到期时间

sub:主题

aud:用户

nbf:在此之前不可用

iat:发布时间

jti:JWT ID用于标识该JWT

除以上默认字段外,我们还可以自定义私有字段,如下例:

1 {
2 
3 "sub": "1234567890",
4 
5 "name": "chongchong",
6 
7 "admin": true
8 
9 }

请注意,默认情况下JWT是未加密的,任何人都可以解读其内容,因此不要构建隐私信息字段,存放保密信息,以防止信息泄露。

JSON对象也使用Base64 URL算法转换为字符串保存。

签名哈希

签名哈希部分是对上面两部分数据签名,通过指定的算法生成哈希,以确保数据不会被篡改。

首先,需要指定一个密码(secret)。该密码仅仅为保存在服务器中,并且不能向用户公开。然后,使用标头中指定的签名算法(默认情况下为HMAC SHA256)根据以下公式生成签名。

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) 在计算出签名哈希后,JWT头,有效载荷和签名哈希的三个部分组合成一个字符串,每个部分用"."分隔,就构成整个JWT对象。

Base64URL算法

如前所述,JWT头和有效载荷序列化的算法都用到了Base64URL。该算法和常见Base64算法类似,稍有差别。

作为令牌的JWT可以放在URL中(例如api.example/?token=xxx)。 Base64中用的三个字符是"+","/"和"=",由于在URL中有特殊含义,因此Base64URL中对他们做了替换:"="去掉,"+"用"-"替换,"/"用"_"替换,这就是Base64URL算法,很简单把。

posted @ 2020-08-06 19:15  王余阳  阅读(203)  评论(0)    收藏  举报