简体   繁体   English

Axios - 刷新令牌循环

[英]Axios - Refresh token loop

so im rather new to axios and context but I have an Auth context that is provided at App level and this context is used by multiple child components.所以我对 axios 和上下文相当陌生,但我有一个在应用程序级别提供的身份验证上下文,并且这个上下文被多个子组件使用。 Within this context I have an axios interceptor that checks requests for 401 (unauthorized) and then calls the refresh token api and replaces the token with a new one.在这种情况下,我有一个 axios 拦截器,它检查 401(未经授权)的请求,然后调用刷新令牌 api 并用新令牌替换令牌。 My only concern is that the second time the refresh token API is called it goes into an endless loop of calling the refresh token api?我唯一担心的是,第二次调用刷新令牌 API 时,它会进入调用刷新令牌 api 的无限循环? Any ideas what im doing wrong?任何想法我做错了什么? Any help would be greatly appreciated.任何帮助将不胜感激。

AuthContext.js 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);
});

I have done something similar to get a refresh token when the token expires and I have encountered the same problem, actually, you are using the same instance of Axios, create another instance我做了类似的事情来在令牌过期时获取刷新令牌并且我遇到了同样的问题,实际上,您使用的是 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;
}

Hope the above example will help you希望上面的例子对你有帮助

Hey I know this is an old question, but it seems that your problem was using the same axios instance to request a refresh token, essentially creating a nested refresh-token cycle.嘿,我知道这是一个老问题,但您的问题似乎是使用相同的 axios 实例来请求刷新令牌,本质上是创建一个嵌套的刷新令牌周期。 What you could do is create a new axios instance (alongside with the initial instance, you would use them both) without an interceptor like this: const noInterceptAxios = axios.create();您可以做的是创建一个新的 axios 实例(与初始实例一起,您将同时使用它们)而不使用这样的拦截器: const noInterceptAxios = axios.create(); , and then later use it to send requests where you don't need to check the access token, return noInterceptAxios.post(`/Identity/Refresh).then().catch() . ,然后稍后使用它发送不需要检查访问令牌的请求, return noInterceptAxios.post(`/Identity/Refresh).then().catch()

@J.Naude I have done he similar thing but a generic wrapper around axios which i wrote for one of my project that handles almost all the edge cases @J.Naude 我做了类似的事情,但是我为我的一个项目编写了 axios 的通用包装器,它处理了几乎所有的边缘情况

https://gist.github.com/tapandave/01960228516dd852a49c74d16c0fddb1 https://gist.github.com/tapandave/01960228516dd852a49c74d16c0fddb1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM