前端刷新token?如何实现无痕刷新?

659 阅读2分钟

谈谈刷新token是如何实现的?

在登陆接口中返回了toke和refresh_token,在token过期时,前端需要拿到refresh_token去进行对token的刷新,将旧token替换掉,这种操作叫做刷新token;

token刷新后怎么要拿到失效的接口,再次发起请求呢,同时要怎么做到没有影响到用户体验的情况下再次调用接口呢?

算了 直接上代码吧,在写这个需求之前,我猜测你们肯定已经百度过要怎么写了,有哪些方案,要如何实现,他们是怎么实现的,有什么区别都会有一点的了解,所以在这我也不做太多的解释,会写这个的人,也不会看到这个东西,不懂得我觉得看一遍你不一定会懂,但是把东西做出来应该没问题,至于原理的话,你就慢慢去研究吧;

看下代码是如何实现的:

  • 首先我们需要定义一个class
// 重新请求
class ReRequest {
 // 刷新token
 refreshToken(config) {
   const refreshToken = StorageUtil.get(
     StorageConst.STORAGE_KEY_REFRESH_TOKEN
   );
   return new Promise((resolve, reject) => {
     instance
       .post(Vue.prototype.$webInterface.API_LOGIN, {
         grant_type: 'refresh_token',
         refresh_token: refreshToken,
       })
       .then((responseProcess) => {
         if (responseProcess.ok) {
           let { accessToken } = responseProcess.data;
           StorageUtil.set(StorageConst.STORAGE_KEY_TOKEN, accessToken);
           instance.defaults.headers.common[
             'Authorization'
           ] = `Bearer ${accessToken}`;
           config.headers.Authorization = `Bearer ${accessToken}`;
           resolve();
         } else {
           if (responseProcess.retCode === '100110') {
             reject('刷新token失败,refreshToken已过期');
             router.push({
               name: 'Login',
               params: {
                 routeFullPath: router.currentRoute.fullPath,
               },
             });
           }
           reject('刷新token失败');
         }
       })
       .catch((error) => {
         reject(error);
       });
   });
 }

二: 需要重新请求接口

 // 重新请求
  reRequest(config) {
    config.reRequest = true;
    config.reRequestCount++; // 重新请求的次数
    return instance(config);
  }

以上操作是为了什么? 我也懒得讲如果不懂就照着抄,多看几次就回来,我并不觉得一个正常人看一遍就会了,知识是需要自己积累的,至于什么时候去调用刷新token,在上面我也说了,是需要根据token过去才会调用,那么怎么知道他是不是过期,肯定是在响应拦截器里面根据状态码来确定了,具体在看代码吧

 if (response) {
      let { data, status } = response;
      if (status === 401 || status === 403) {
        let systemMessage = await getProcessedSystemMessage(responseType, data);
        let { retCode } = systemMessage;
        if (retCode === '100401') {
          config.reRequestCount = config.reRequestCount ?? 0;
          if (config.reRequestCount > 2) {
            return Promise.reject(
              '当前接口已重新请求了三次,为防止递归调用,已终止接口重新请求'
            );
          } else {
            let reRequest = new ReRequest();
            return reRequest
              .refreshToken(config)
              .then(() => {
                return reRequest.reRequest(config);
              })
              .then((response) => {
                return response;
              })
              .catch((error) => {
                return Promise.reject(error);
              });
          }
        } else if (retCode === '100403') {
          router.push('/home');
        }
        return Promise.reject(); // 不传参数,是为了终止代码,防止弹框
      }

上面的两个状态码,100401是后端定义的token过期码,剩下的两个如果你不懂我建议你转行,回家养猪吧,能做到这一块还不懂,我不建议你继续往后学习了,今天就到这里,拜勒个拜,不懂的可以多看看,一次不行就多来几次,一边看一边写,总有那么一阵时间,哦 原来是这样很简单嘛,那傻逼博主还写这么多的代码,我***** 不过,我还是很希望你会有这样的时刻.