JWT技术(基于token的鉴权机制)全称JSON Web Token,是一种基于JSON的,用于在网络上声明某种主张的令牌(Token)。
流程上是这样的:
-
用户使用用户名密码来请求服务器
-
服务器进行验证用户的信息
-
服务器通过验证后生成一个token发送给用户
-
客户端存储token,并在每次请求时附送上这个token值
-
服务端验证token值,并返回数据
JWT是由三段信息(header.payload.signature)构成的,将这三段信息文本用英文句号链接一起就构成了JWT字符串。
- 第一部分我们称它为头部(header),即声明 类型 和 加密的算法。然后将头部进行base64加密,就构成了header部分。
//完整的头部就像下面这样的JSON:
{
'typ': 'JWT',
'alg': 'HS256'
}
- 第二部分我们称其为承载(payload,),
这些有效信息包含三个部分声明(Claims)
标准中注册的声明
公共的声明
私有的声明
标准中注册的声明 (建议但不强制使用) :
iss: jwt签发者
sub: jwt所面向的用户
aud: 接收jwt的一方
exp: jwt的过期时间,这个过期时间必须要大于签发时间
nbf: 定义在什么时间之前,该jwt都是不可用的.
iat: jwt的签发时间
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
- 第三部分是签证(signature)。
这个部分需要 base64加密后的header 和 base64加密后的payload,使用 英文句号 连接组成的字符串,然后通过header中声明的加密方式,进行secret组合加密,然后就构成了jwt的第三部分signature。
Token的存储一般有两种方式,一种是存在localStorage中,二是存在cookie中,
这两种存储方式都有问题,存在localStorage中有很大的安全隐患,容易造成XSS攻击,因为跨站脚本可以读取localStorage里面的信息,
如果存在cookie中,又容易造成CSRF攻击,这个是由于Cookie存储的安全性造成的(可以使用XSRF Token来解决这个问题)。
失效和刷新问题,token肯定要有失效时间,而且如果用户一直处于活跃状态,则要考虑能自动刷新token。
重放攻击,由于每次都传输token,如果这个token被窃取,那么可以在任何一个地方使用。特别的,如果这个token过期时间很长的话,那么它就相当于一个在很长时间内有效的钥匙。(可以考虑每次请求都重新生成一个token并存储一段时间防重放,但是这样又会遇到存储问题和并发刷新的问题,
设置过期时间
有很多时候,我们并不希望签发的token是永久生效的,所以我们可以为token添加一个过期时间。
解释:
.setExpiration(date)// 用于设置过期时间 ,参数为Date类型数据
当前时间超过过期时间,则会报错
在前端接收到token
后,一般情况会通过localStorage
进行缓存,然后将token
放到HTTP
请求头Authorization
中,关于Authorization
的设置,前面要加上 Bearer ,注意后面带有空格
axios.interceptors.request.use(config => {
const token = localStorage.getItem('token');
config.headers.common['Authorization'] = 'Bearer ' + token; // 留意这里的 Authorization
return config;
})
校验token
使用 koa-jwt
中间件进行验证,方式比较简单
/ 注意:放在路由前面
app.use(koajwt({
secret: 'test_token'
}).unless({ // 配置白名单
path: [/\/api\/register/, /\/api\/login/]
}))