【问题标题】:Axios - Refresh token loopAxios - 刷新令牌循环
【发布时间】:2020-10-01 02:04:44
【问题描述】:

所以我对 axios 和上下文相当陌生,但我有一个在 App 级别提供的 Auth 上下文,并且该上下文被多个子组件使用。在这种情况下,我有一个 axios 拦截器,它检查 401(未经授权)的请求,然后调用刷新令牌 api 并将令牌替换为新令牌。我唯一担心的是,第二次调用刷新令牌 API 时,它会进入调用刷新令牌 API 的无限循环吗?任何想法我做错了什么?任何帮助将不胜感激。

AuthContext.js

  axios.interceptors.response.use((response) => {
    return response
  }, function (error) {
    const originalRequest = error.config;

    if (error.response.status === 401 && originalRequest.url ===
      `${BASE_URI}/Identity/Login`) {
      history.push('/login');
      return Promise.reject(error);
    }

    if (error.response.status === 401 && !originalRequest._retry) {
      originalRequest._retry = true;
      const localStorage = JSON.parse(sessionStorage.getItem(AUTH_USER))
      const refreshToken = localStorage.refreshToken;
      return axios.post(`${BASE_URI}/Identity/Refresh`, null,
      {
        headers: {
          'Refresh-Token': refreshToken
        }
      })
      .then(res => {
        if (res.status === 201 || res.status === 200) {
          console.log("In refresh request !")
          console.log(res)
          setSession(null, res.data.token, res.data.refreshToken)
          axios.defaults.headers.common['authorization'] = 'Bearer ' + res.data.token;
          return axios(originalRequest);
        }
      }).catch((error) => {
          console.log("Inside error refresh")
          return Promise.reject(error);
      })
  }
  return Promise.reject(error);
});

【问题讨论】:

    标签: reactjs axios react-hooks interceptor react-context


    【解决方案1】:

    我做了类似的事情来在令牌过期时获取刷新令牌,我也遇到了同样的问题,实际上,你使用的是同一个 Axios 实例,创建另一个实例

    const instance = axios.create();
    
    axios.interceptors.request.use(async (config) => {
        if (token && refreshToken) {
            const data = JSON.parse(atob(token.split('.')[1]));
            const time = Math.floor(new Date().getTime() / 1000);
            if (data.exp < time) {
                 instance.defaults.headers.common["Authorization"] = `Bearer ${refreshToken}`;
                 const { data } = await instance.get(SERVER.API_ROOT + '/tokens/refresh');
                 if (data?.AccessToken) localStorage.setItem(config.AUTH_TOKEN, data.AccessToken)
                    else localStorage.clear();
                }
         return config;
    }
    

    希望上面的例子对你有帮助

    【讨论】:

      【解决方案2】:

      嘿,我知道这是一个老问题,但您的问题似乎是使用同一个 axios 实例来请求刷新令牌,本质上是创建一个嵌套的刷新令牌循环。您可以做的是创建一个新的 axios 实例(与初始实例一起,您将同时使用它们),而不使用像这样的拦截器:const noInterceptAxios = axios.create();,然后使用它发送不需要检查的请求访问令牌,return noInterceptAxios.post(`/Identity/Refresh).then().catch()

      【讨论】:

        猜你喜欢
        • 2022-06-14
        • 2019-06-14
        • 1970-01-01
        • 1970-01-01
        • 2019-08-21
        • 2021-06-12
        • 2022-11-03
        • 2021-08-20
        • 2021-02-11
        相关资源
        最近更新 更多