JWT的流程详解
JWT流程总览
- 用户端发送登录请求携带账号以及密码
或者其他登录方式都可以
服务端验证并通过请求后开始生成token,并返回到客户端
客户端接收到token后需要存在本地,以做后续请求的验证
此后的每一次客户端发送的请求都会携带token
服务端会在中间件进行拦截,过滤非法的请求
token可以设置有效时间,通常情况下最好设置一个有效时间
- 服务端可以通过token解密出一开始就存储的对象信息
服务端验证通过登录请求后生成token
用户端发送登录请求就不在多说了,直接开始正文部分
- 服务端首先会定义token的header头信息,里面包括了加密算法和token的类型
{
"typ": "JWT",
"alg": "HS256"
}
- 然后会在payload(负载)里存入对象数据
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
此处负载官网有推荐的信息,除此之外还能添加额外的信息,但是有一点要注意,token的加密方法是对称加密,意味着这些信息可以被解密,所以都是明文
- 最后生成签名,利用base64加密后的前部分信息,通过header指定的加密算法,组合秘钥加盐最后生成的
var encodedString = base64UrlEncode(header) + "." + base64UrlEncode(payload);
HMACSHA256(encodedString, 'secret');
- 最后三者通过
.
连接,然后返回给客户端
客户端发送请求的时候如何携带token
客户端接收token后会通过本地缓存的方式存储token
然后会在之后的每次请求的请求头里面加入Authorization并加上Bearer标注
fetch('api/user/1', {
headers: {
'Authorization': 'Bearer ' + token
}
})
服务端中间件接收后如何拦截
首先服务端接收token会将header以及payload再次base64编码,然后按照header指定的加密方式,再次进行加密,然后和签名校验下,如果不同,则说明此次请求有被篡改,因此会被过滤掉,并返回错误信息
那么只要保证秘钥存放在服务端,不会泄露,那么token基本上是安全的
本文借鉴于基于jwt的token验证