基于JWT的Token认证机制实现(一)概念

JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。

JWT的组成

一个JWT实际上就是一个字符串,它由三部分组成:头部、载荷与签名。将这三段信息文本用.链接一起就构成了Jwt字符串。就像这样:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

头部(Header)

JWT的头部承载两部分信息:
1、声明类型,这里是jwt
2、声明加密的算法,通常直接使用 HMAC SHA256

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

在头部指明了签名算法是HS256算法。

载荷(Payload)

载荷就是存放有效信息的地方。这个名字像是特指飞机上承载的货品,这些有效信息包含三个部分
1、标准中注册的声明
2、公共的声明
3、私有的声明

标准中注册的声明 (建议但不强制使用) :
1、iss(Issuer):  签发人
2、sub(Subject):  主题
3、aud(Audience):  受众
4、exp(Expiration Time):  过期时间,这个过期时间必须要大于签发时间
5、nbf(Not Before):  生效时间
6、iat(Issued At):  签发时间
7、jti(JWT ID) :  JWT的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

公共的声明 :
公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.

私有的声明 :
私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。

定义一个payload:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

然后将其进行base64加密,得到Jwt的第二部分。

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9

签名(Signature)

JWT的第三部分是一个签证信息,这个签证信息由三部分组成:

1、header (base64后的)

2、payload (base64后的)

3、secret

这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了JWT的第三部分。

Signature = HMACSHA256(base64UrlEncode(header) + "." +  base64UrlEncode(payload), secret);

Token = base64(头部).base64(载荷).Signature

 

注意:secret是保存在服务器端的,在任何场景都不应该流露出去。

如何应用

一般是在请求头里加入Authorization,并加上Bearer标注:

fetch('api/user/1', {
  headers: {
    'Authorization': 'Bearer ' + token
  }
})

服务端会验证token,如果验证通过就会返回相应的资源。整个流程就是这样的:

 

 





参考文章:

https://www.jianshu.com/p/576dbf44b2ae
https://www.cnblogs.com/xiekeli/p/5607107.html
https://www.cnblogs.com/dinglinyong/p/6611151.html
https://blog.csdn.net/m0_37859660/article/details/82716162
https://blog.csdn.net/mn_kw/article/details/80522565
https://blog.csdn.net/xunfeng13/article/details/52371562/

posted on 2020-06-30 16:27  麦克煎蛋  阅读(1891)  评论(0编辑  收藏  举报