前端处理实时刷新refresh_token的使用

响应拦截器拦截状态码401刷新token

// 是否正在刷新的标记
let isRefreshing = false;
// 重试队列,每一项将是一个待执行的函数形式
let requestsList = [];
service.interceptors.response.use(
  response => {
    return response.data;
  }, err
);
const err = (error) => {
  if (error.response) {
    let data = error.response.data
    const token = Vue.ls.get(ACCESS_TOKEN)
    switch (error.response.status) {
  case 401:
        if (error.response.data.code == 401 && error.response.config.url !== "/sys/logout") {
          var config = error.config; //获取401失败请求的axios中的config配置数据
          // 拿到刷新token
          const refreshtoken = Vue.ls.get(ACCESS_TOKEN_REFRESH);
          // 判断 没有刷新token的处理代码
          if (!refreshtoken) {
            // 清除过期token
            // 跳转到login
            Vue.prototype.$Jnotification.error({ message: '系统提示', description: '很抱歉,登录已过期,请重新登录', duration: 4 })
            store.dispatch("Logout").then(() => {
              setTimeout(() => {
                window.location.reload();
              }, 1500);
            });
            return;
          }
          // 有刷新token
          // 要try catch 因为刷新token一般14天过期 有可能还会获取不到refresh_token
          if (!isRefreshing) {
            isRefreshing = true;
            let data = {
              refreshToken: Vue.ls.get(ACCESS_TOKEN_REFRESH),
              loginFrom: 1,
              username: Vue.ls.get(USER_NAME),
            };
            refreshTokenToToken(
              data
            ).then(res => {
              if (res.code == 200) {
                var token = res.result.token;
                Vue.ls.set(ACCESS_TOKEN, res.result.token, 7 * 24 * 60 * 60 * 1000);
                Vue.ls.set(ACCESS_TOKEN_REFRESH, res.result.refreshToken, 7 * 24 * 60 * 60 * 1000);
                config.headers['X-Access-Token'] = token;
                // 已经刷新了token,将所有队列中的请求进行重试
                requestsList.forEach(cb => cb(token));
                // 重试完了别忘了清空这个队列
                requestsList = [];
                return service.request(error.config)
              } else {
                Vue.prototype.$Jnotification.error({ message: '系统提示', description: '很抱歉,登录已过期,请重新登录', duration: 4 })
                store.dispatch("Logout");
                window.location.reload();
              }
            })
              .catch(error => {
                Vue.prototype.$Jnotification.error({ message: '系统提示', description: '很抱歉,登录已过期,请重新登录', duration: 4 })
                store.dispatch("Logout");
                window.location.reload();
              })
              .finally(() => {
                isRefreshing = false;
              });
          } else {
            // 正在刷新token,将返回一个未执行resolve的promise
            // 保存函数 等待执行
            // 吧请求都保存起来 等刷新完成后再一个一个调用
            return new Promise((resolve) => {
              // 将resolve放进队列,用一个函数形式来保存,等token刷新后直接执行
              requestsList.push((token) => {
                config.headers['X-Access-Token'] = token
                resolve(service(config))
              })
            })
          }
        }
        break
      default:
        Vue.prototype.$Jnotification.error({
          message: '系统提示',
          description: data.message,
          duration: 4
        })
        break
    }
  } else if (error.message) {
    if (error.message.includes('timeout')) {
      Vue.prototype.$Jnotification.error({ message: '系统提示', description: '网络超时' })
    } else {
      Vue.prototype.$Jnotification.error({ message: '系统提示', description: error.message })
    }
  }
  return Promise.reject(error)
};
// 刷新token
function refreshTokenToToken(data) {
  return service
    .post(
      "/sys/refreshToken",
      data
    )
    .then(result => {
      return Promise.resolve(result);
    });
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值