vue token过期

1.路由守卫

router.beforeEach((to, from, next) => {
  if (to.path.startsWith('/list')) {
    // 判断token
    if (store.state.tokenInfo.token) {
      next()
    } else {
      next({
        path: '/login',
        query: {
          // 登录成功回到目标页
          backto: to.fullPath // fullPath 会拿到路由后面的查询字符串
        }
      })
    }
  } else {
    next()
  }
})

2.axios设置响应拦截

const instance = axios.create({

  //代理服务器地址
  baseURL: 'xxxx'
})
instance.interceptors.request.use(function (config) {
  // 从vuex中取出token
  const token = store.state.tokenInfo.token
  // 如果有token则 添加到headers中
  if (token) {
    config.headers.Authorization = `Bearer ${token}`
  }
  return config
}, function (error) {
  return Promise.reject(error)
})
// 添加响应拦截器处理token过期
instance.interceptors.response.use(function (response) {
  return response
}, async function (error) {
  // 如果是token过期
  if (error.response.status === 401) {
    // 从vuex中取出token
    const refreshToken = store.state.tokenInfo.token
    // 是否有refreshToken
    if (refreshToken) {
      // 用refresh_token 重发请求 再次取回一个有效期的
      try {
        const res = await axios({
          method: 'PUT',
          url: 'xxxx',
          headers: {
            Authorization: `Bearer ${refreshToken}`
          }
        })
        // 定义赋值新的token
        const newToken = res.data.token
        // 更新vuex
        store.commit('mUpdateToken', newToken)
        // 再发请求
        return instance(error.config)
      } catch {

         // 如果没有拿到新的token
        // 回登录页
        router.push({
          path: '/login',
          query: {
            // currentRoute表示当前路由对象
            backto: router.currentRoute.fullPath
          }
        })
      }
    } else { // 如果没有refreshToken
      router.push({
        path: '/login',
        query: {
          backto: router.currentRoute.fullPath
        }
      })
    }
  } else { // 如果不是token错误
    return Promise.reject(error)
  }
})

3.vuex状态管理,更新token

export default new Vuex.Store({
  state: {
    // 保存公共数据
    tokenInfo: getItem('tokenInfo') || {}
  },
  mutations: {
    mSetTokenInfo (state, tokenObj) {
      state.tokenInfo = tokenObj
      // 因为刷新会丢失所以进行持久化 调用storage方法
      localStorage.setItem('tokenInfo', tokenObj)
    }
  },
  // 只更新token 不更新响应拦截器里面的refreshToken
  mUpdateToken (state, newToken) {
    state.tokenInfo.token = newToken
    localStorage.setItem('tokenInfo', state.tokenInfo)
  },
  actions: {
  },
  modules: {
  }
})

 

 

posted @ 2022-03-14 10:09  三又二分之一  阅读(553)  评论(0)    收藏  举报