功能背景:后端技术调整后token过期非常短,短到10分钟就过期了,所以在登录之后会给前端一个refreshToken字段同AccessToken一并传过来。token失效后利用refreshToken去延长用户的登录信息
1.功能难点
一个页面请求一个接口报401权限错误后,需要调用一个刷新AccessToken的接口,传入refreshToken更新token信息。同时,在请求到token之后,继续请求上一步出错的接口。用户并不会知道自己的登录信息已经过期了。
2.解决办法
- 在vue项目中,我们采用 axios 来请求接口,一般我们都会对axios进行一次封装 $http,然后可以选择把封装好的 axios 绑定在vue原型上,这样我们就可以在组件中用this.$http来请求接口了。
- this.$http请求返回的是一个promise,在请求之前axios有自己的拦截器(interceptors),对请求进行拦截处理,一般的我们判断接口401的时候,会跳转到登录页,就可以在拦截器中统一做处理 。
- 上一步确定了在拦截器里面可以做处理。所以我们只需要在接口请求出错,并且状态status是401的时候,在拦截器的response,error回调函数去请求refreshToken接口,等到refreshToken接口返回了token之后,再return 请求上一步请求的接口继续请求,否则return reject。
3.例子
axios.interceptors.response.use(success, async (error) => {
let {status} = error.response;
if (status == 401) {
let res = await getrefreshToken(refreshToken);
window.localstorage.token = res.token;
return axios.request(error.config);
}
return Promise.reject()
})
4.总结
一开始不太明白怎么在接口401之后请求完refreshToken之后,再去请求上一个出错的接口。后来一想,axios返回的是一个promise,只要状态没改变,那么then就不会执行,一直在pending中,所以,在拦截器中error回调函数中去做处理,等请求到token之后在,重新请求一遍上一次报错的接口,再return 这个promise,那么在其他页面的地方就不需要做什么处理,promise的状态改变后,就直接会进then或者catch方法里了。
网友评论