记录无感刷新token的思路

无痛/无感刷新token的思路:

背景:
  • token有效期只有2小时,保证数据的安全
  • token失效了之后,不能直接拦截到登录页(用户体验不好)
目标:
  • 在token过期失效的时候,自动刷新token
思路:
  1. 配置axios的响应拦截器
  2. 通过响应拦截器捕获401异常
  3. 判断error.response.status是否是401
  4. 如果不是401,说明不是由于token过期导致,不用管。
  5. 如果错误码是401,说明token过期了。判断vuex中是否有refresh_token刷新token
  6. 如果没有,直接拦截到登录页面(删除vuex中token,跳转到登录页,提示)
  7. 如果有refresh_token, 拿着刷新token重新新的token。
  8. 如果成功了,获取到新的token,并且更新到vuex中。重新发送一个请求(才能保证用户无感)
  9. 如果失败了,直接拦截到登录页面(删除vuex中token,跳转到登录页,提示)
import axios from 'axios'
//  因为不是在组件中,所以要导入store router 另外导入了vant-ui的Toast组件
import store from '@/store'
import router from '@/router'
import { Toast } from 'vant'

// 添加响应拦截器
request.interceptors.response.use(function (response) {
  return response.data
}, async function (error) {
  // console.dir(error)
  // 判断状态码
  if (error.response.status === 401) {
    // 拿到刷新token
    const refreshtoken = store.state.user.token.refresh_token
    // 判断 没有刷新token的处理代码
    if (!refreshtoken) {
      // 清除过期token  
      store.commit('user/removeToken')
      // 跳转到login
      router.push({
        path: '/login',
        query: {
          back: router.currentRoute.path
        }
      })
      Toast.fail('登录过期')
      return
    }
    // 有刷新token
    // 要try catch 因为刷新token一般14天过期 有可能还会获取不到refresh_token
    try {
      const res = await axios({
        method: 'PUT',
        url: baseURL + 'v1_0/authorizations',
        headers: {
          Authorization: 'Bearer ' + refreshtoken
        }
      })
      // console.log(res) // res.data.data.token
      store.commit('user/setToken', {
        token: res.data.data.token,
        refresh_token: refreshtoken
      })
      //  重新发送请求
      return request(error.config)
    } catch {
      store.commit('user/removeToken')
      router.push({ path: '/login', query: { back: router.currentRoute.path } })
      Toast.fail('登录失效')
    }
  } else {
    return Promise.reject(error)
  }
})


其中要注意的是:
  • console.dir(error) 能够获取到错误信息。比如:response中的status、和config中的请求信息等等
打印响应拦截器中error对象
  • 因为不是在组件中,无法直接使用$route.path,可以通过router.currentRoute,等于是当前路由对应的路由信息对象。

你可能感兴趣的:(记录无感刷新token的思路)