基于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/