(1)可以通过响应拦截器或者全局前置守卫强制跳转登录页
// 全局前置守卫router.beforeEach((to, from) => {let token = sessionStorage.token;if (token) {return true} else {return { name: 'Login', query: { redirect: to.fullPath } };}})
// 添加响应拦截器axios.interceptors.response.use(function (response) {// 2xx 范围内的状态码都会触发该函数。}, function (error) {// 超出 2xx 范围的状态码都会触发该函数。// 对响应错误做点什么let { response: { status } ,config:{url}} = error//消息提示switch (status) {case 401: ElNotification.error({title: `错误${status}`,message: '登陆的token过期或者无效请重新登录',});// 获取当前页面路径let { fullPath } = router.currentRoute.value// 重定向到登陆页面,附带redirect参数router.replace({ name: 'Login', query: { redirect: fullPath } })break;case 403: ElNotification.error({title: `错误${status}`,message: '登陆的token过期或者无效请重新登录',});break;}});
但这样面临着问题
无感刷新token
(2)双token
有一些项目token过期获取新的token时候,不止获取access_token,虽然refresh_token没有过期,也会获取,也就是说两个token都获取并更新存放在浏览器中。
(三)使用旧token获取新token
如果采取单个token的方式要实现token的自动刷新,就必须使用定时器,每隔一段时间自动刷新token,并且这个时候token一定要是没有过期的,因为如果已经过期的token也可以用来刷新,这和长期有效的token也没什么不同。但这种方式存在一定的问题:
为了保证同一时间,账户只被单个用户登录,后端必然要保证一个账户的多个token只有一个生效,最简单的方式就是使用分布式缓存中间件如redis,而存在并发请求时,可能前一个请求带着的是旧token,此时又到了刷新token的时间,就会产生请求的token与服务端存储的token不一致的问题
使用定时器是增加了性能的损耗,不是最佳的手段