uniapp refreshToken刷新token思路以及实例

1,757 阅读1分钟

工具

  1. luch-request
  2. pinia

思路

  1. 请求前拦截放开拦截
  2. 在请求后401拦截处理
  3. 通过设定标识 isRefreshing 来判断是否在请求中拦截添加队列 requestList
  4. 通过await阻塞token请求过程
  5. 循环执行 requestList
  6. 重新本次发送请求

实例

import Request from 'luch-request';
import { useUserStore } from '@s/user';

// 请求实例
const http = new Request({
  baseURL:'/api'
  timeout: 15000, // 请求超时时间毫秒
  header: { 'Content-Type': 'application/x-www-form-urlencoded' },
});

// 请求前拦截
http.interceptors.request.use(async (config) => {
  const store = useUserStore();
  config.header = {
    ...config.header,
    Authorization: 'Bearer ' + store.accessToken,
  };
  return config;
});
// 刷新token标识
let isRefreshing = false;
// token队列
let requestList = [];
// 请求后拦截
http.interceptors.response.use(
  async (response) => {
    return Promise.resolve(response.data);
  },
  async (error) => {
    console.log('-> error', error);
    let { config } = error;
    const userStore = useUserStore();
    //如果是401
    if (error.statusCode == 401) {
      //如果没有更新标识
      if (!isRefreshing) {
        // 开启更新标识
        isRefreshing = true;
        console.log('开始刷新token');
        //带上refresh_token拿到token 并替换现有token
        await userStore.login(userStore.token.refresh_token);
        //执行请求列表
        requestList.forEach((cb) => cb());
        console.log('执行完成');
        // 重试完了清空这个队列
        requestList = [];
        //还原标识
        isRefreshing = false;
        //重新执行本次请求
        return http.request(config);
      } else {
        return new Promise((resolve) => {
          // 将resolve放进队列,用一个函数形式来保存,等token刷新后直接执行
          requestList.push(() => {
            resolve(http.request(config));
          });
        });
      }
    }
    // 请求错误做点什么。可以使用async await 做异步操作
    return Promise.reject(error);
  },
);

export default http;