Axios 令牌刷新拦截器

问题描述 投票:0回答:1

我正在使用 Axios 拦截器来获取带有刷新令牌的新访问令牌。以下代码从服务器创建新的访问令牌,但我在浏览器中找不到 cookie。

工作正常,但浏览器在加载时发生故障。

如果有人能找到问题所在,这可能会很有帮助。

提前致谢。


interface RetryQueueItem {
  resolve: (value?: any) => void;
  reject: (error?: any) => void;
  config: AxiosRequestConfig;
}

const fetchAxiosClient: AxiosInstance = axios.create({
  baseURL: 'http://localhost:8080/api/v1',
  timeout: 60000
});
fetchAxiosClient.defaults.headers.common = {
  'Content-Type': 'application/json',
  'Accept': 'application/json'
} as headers;

export async function createAxiosInstance(requestEvent) {

  // Auth token to request header
  fetchAxiosClient.interceptors.request.use(
    (config: InternalAxiosRequestConfig) => {
      const token = getAccessToken(requestEvent.cookieObj).access_token;
      if (token) {
        config.headers['Authorization'] = `Bearer ${token}`;
      }
      config.headers['Content-Type'] = 'application/json';
      return config;
    },
    error => Promise.reject(error)
  );

  const refreshAndRetryQueue: RetryQueueItem[] = [];
  let isRefreshing = false;

  fetchAxiosClient.interceptors.response.use(
    function (response: AxiosResponse) {
      return response;
    },
    async function (error: any) {
      const originalRequest: AxiosRequestConfig = error.config;
      if (error.response && error.response.status === 401) {
        if (!isRefreshing) {
          isRefreshing = true;
          try {
            const refreshToken = getRefreshToken(requestEvent.cookieObj);
            if (refreshToken) {
              await axios.post(
                `${fetchAxiosClient?.defaults.baseURL}${REFRESH_TOKEN}`,
                {
                  refresh_token: refreshToken,
                }
              ).then(async (response: any) => {
                const cookies = response.headers['set-cookie'] as string[];
                const accessToken = getToken(cookies[0], APP_CONSTANTS.ACCESS_TOKEN);
                setToken(requestEvent.cookieObj, accessToken!);
                return fetchAxiosClient!(originalRequest);
              }).catch((error) => {
                requestEvent.cookieObj.delete(APP_CONSTANTS.ACCESS_TOKEN, { path: '/' });
                throw requestEvent.redirect(302, '/login');
                //return Promise.reject(error);
              });
              refreshAndRetryQueue.forEach(({ config, resolve, reject }) => {
                fetchAxiosClient!(config)
                  .then((response) => resolve(response))
                  .catch((err) => reject(err));
              });
              refreshAndRetryQueue.length = 0;
            } else {
                requestEvent.cookieObj.delete(APP_CONSTANTS.ACCESS_TOKEN, { path: '/' });
              window.location.href = "/";
              return Promise.reject(error);
            }
          } catch (refreshError) {
            refreshAndRetryQueue.length = 0;
            requestEvent.cookieObj.delete(APP_CONSTANTS.ACCESS_TOKEN, { path: '/' });
          } finally {
            isRefreshing = false;
          }
        }
        return new Promise<void>((resolve, reject) => {
          refreshAndRetryQueue.push({ config: originalRequest, resolve, reject });
        });
      }
      return Promise.reject(error);
    }
  );
}

新生成的访问令牌将在 15 分钟后过期,应设置为 cookie。访问令牌过期后,应使用刷新令牌生成新的访问令牌。

但是,访问令牌过期后,在生成新的访问令牌时,浏览器显示加载指示器并持续忙碌。

reactjs cookies axios qwikjs
1个回答
0
投票

代码逻辑看起来很乱。使用这个插件可以让你的代码更容易:

https://github.com/Flyrell/axios-auth-refresh

© www.soinside.com 2019 - 2024. All rights reserved.