这里是文章模块栏目内容页
uni.request实现401状态刷新token重新登陆

在app的请求里面,refresh token 是必须实现的;

当采用jwt的方式生成token, 把refresh的token也一起生成; refreshtoken生成也是jwt的方式,只是它的用途只能访问刷新token 的接口,确保安全;

刷新token其实是给客户端生成新的jwt,token,失效日期为当前时间 + 2小时后到期;

到期后又重新刷新一次;每次刷新都同时把新生成的token和refresh token发给客户端保存起来,用于下一次的流程;


class http {
  /**
   * http 请求基类
   * @param {string} baseUrl 根地址
   * @param {object} header 请求头
   */
  constructor(baseUrl = process.env.VITE_GLOB_API_URL, header = {}) {
    // 启用请求拦截器
    requestInterceptor();

    this.baseUrl = baseUrl;
    this.header = header;

    // 请求缓存
    this.responseCache = [];
    // 是否在刷新token
    this.isRefreshToken = false;
  }
  /**
   * 发送请求
   * @param {object} requestData 请求数据 {url: url路径, params: url参数}
   * @param {Function} request 回调方法
   */
  response({ method, url, data, params, responseType }) {
    // 构造请求
    const responsePromise = () => {
      // 设置token
      const user = useStoreUser();
      this.header.Token = user.getToken;
      return new Promise((resolve, reject) => {
        const _this = this;
        uni.request({
          method,
          header: _this.header,
          url: _this.joinUrl(_this.baseUrl + url, params),
          data,
          responseType: responseType,
          success(res) {
            const data = res.data;
            if (res?.statusCode == 200 && data.code == 200) {
              resolve(data.result);
            } else {
              if (res?.statusCode == 401 || data.code == 401) {
                // 刷新token 401
                if (url == '/login/refreshToken') return reject(data.message);
                // 缓存401请求
                _this.responseCache.push(responsePromise);
                // 刷新token
                if (_this.isRefreshToken == false) {
                  refreshToken()
                    .then((res) => {
                      // 设置新token、refreshToken
                      user.setToken(res.token);
                      user.setRefreshToken(res.refreshToken);
                      // 重新发起缓存401请求队列
                      _this.responseCache.forEach((fun) => {
                        fun().then(resolve).catch(reject);
                      });
                      // 清空401请求队列
                      _this.responseCache = [];
                    })
                    .catch(() => {
                      // 刷新token失败,跳转登录
                      goLogin();
                    })
                    .finally(() => {
                      _this.isRefreshToken = false;
                    });
                  _this.isRefreshToken = true;
                }
              } else {
                _this.errorTip(data.message);
                reject(data.message);
              }
            }
          },
          fail(err) {
            _this.errorTip(err);
            reject(err);
          },
          complete() {}
        });
      });
    };

    // 发起请求,返回结果
    return responsePromise();
  }
  
 }

好了,本文内容全部结束,感谢您的阅读,希望能帮助到您。


更多栏目
相关内容