怎么实现无痛刷新token

最近遇到这个需求,前端登录后,后端返回  access_token 和 refresh_token ,当token 过期时用旧的 refresh_token 去获取新的token,前端要不痛去刷新token 并用新请求的token 去将用户发送的请求执行完 并返回希望的数据。

我这里用的时axios 来实现,在拦截器中去做相应的处理axios.interceptors.response.use()方法。

首先说明一下,项目中的token是存在localStorage中的。

比如返回的一个状态值时token过期的状态  那我们将在这个状态下去处理,如果时同时又多个请求发送过来的话  需要将请求存起来

当第二个过期的请求进来,token正在刷新,我们先将这个请求存到一个数组队列中,想办法让这个请求处于等待中,一直等到刷新token后再逐个重试清空请求队列。 那么如何做到让这个请求处于等待中呢?为了解决这个问题,我们得借助Promise。将请求存进队列中后,同时返回一个Promise,让这个Promise一直处于Pending状态(即不调用resolve),此时这个请求就会一直等啊等,只要我们不执行resolve,这个请求就会一直在等待。当刷新请求的接口返回来后,我们再调用resolve,逐个重试。

下面时我实现的代码

let retryRequest = [] //存放token 过期的请求
let isRefresh = false // 是否在请求新的token

// HTTPresponse拦截
axios.interceptors.response.use(res => {
    const status = Number(res.status) || 200
    if (status === 401) {
    if (!isRefresh) {
      isRefresh = true
      return store.dispatch('RefreshToken',store.getters.refresh_token).then(data => {
       // 这里是去请求新的token 并返回promise 然后保存新的token
        store.commit('SET_ACCESS_TOKEN', data.data.access_token)
        store.commit('SET_REFRESH_TOKEN', data.data.refresh_token)
        res.config.headers['Authorization'] = data.data.access_token
        retryRequest.forEach(cb => {
          cb(data.data.access_token)
        })
        isRefresh = false
        retryRequest = []
        return axios(res.config)
      })
    }else {
      return new Promise((resolve) => {
        // 将resolve放进队列,用一个函数形式来保存,等token刷新后直接执行
        retryRequest.push((token) => {
          res.config.headers['Authorization'] = token
          resolve(axios(res.config))
        })
      })
    }
  }

}

 第一次的请求没有放到那个队列中

原文地址:https://www.cnblogs.com/buxiugangzi/p/12040030.html