概述
Json Web Token,一般用于用户认证(前后端分离/微信小程序/app开发)。前端发送用户名密码到后端进行验证。验证成功后,后端生成一段随机字符串,即Token,并将其返回给前端/浏览器。之后前端发送请求都会携带Token,并用Token在后端校验。
传统Token流程
- 用户登录,服务端返回token,并将token保存在服务端。
- 用户再访问,携带token,服务端获取token后,再去数据库/缓存中获取token并校验
jwt流程
- 用户登录,服务端返回token,服务端不保存token。
- 用户再访问,token存储在请求Header中的Authorization,服务端获取token后,利用算法进行token的校验。
优势:相较于传统token,jwt不需要再服务端保存token
jwt实现过程
- 用户提交用户名和密码给服务端,登陆成功后使用jwt创建一个token,并返回给用户。
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
jwt生成的token是由三段字符串组成,并用.
连接起来。
第一段字符串:HEADER(头部),包含使用的算法和token类型。
{
"alg": "HS256",
"typ": "JWT"
}
json转换成字符串,然后做base64url编码,生成第一段字符串。
第二段字符串:PAYLOAD(载荷),包含需要返回给用户的数据。
{
"sub": "1234567890",
"name": "John Doe",
"exp": 1516239022 # 超时时间,表示token多久后会失效
}
json转换成字符串,然后做base64url编码,生成第二段字符串。base64url编码后可以解码,所以payload内不应该传递敏感信息,例如密码等。
第三段字符串:VERIFY SIGNATURE(签证),将header和payload用.
连接起来的字符串进行加密,使用的加密算法是header中的alg,进行加盐(secret key)组合加密。最后对加密后的密文再做base64url编码。
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret # 盐
) secret base64 encoded
注意secret key是用来签发和验证jwt的凭据,任何情况下都不应该泄露。一旦泄露必须更换secret key。为了安全起见,secret key应该定期更换。
- 用户再次访问时需携带token,后端对token进行校验。
首先通过.
将token切割成三部分;然后对payload密文进行base64url解密并获取payload明文,通过exp内容检测是否超时;最后将header和payload密文进行哈希256加密+加盐,与verify signature密文通过base64解密的内容相比较,如果相等,表示token未被修改过,即认证通过。
jwt应用
一般是放于请求头中,加入Authorization
,并加上Bearer
标注:
fetch('api/user/1', {
headers: {
'Authorization': 'Bearer' + token
}
})