Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling refresh token by recall same request after refreshing the token #39

Open
MhamedRamadan10 opened this issue Aug 6, 2019 · 7 comments

Comments

@MhamedRamadan10
Copy link

MhamedRamadan10 commented Aug 6, 2019

Hi,
I am trying to make a common interceptor to authorize all my outgoing requests.

My logic is as follows:

All my outgoing requests/API calls passes through the interceptor first to check on my token expiry and in-case the response was un-authorized I make an internal call to refresh the token and update my storage keys with the new values.

Now I need to recall the original request with the new token value, but I can't figure out how to detect the original request that passed through the interceptor.

This is my code :

export  const unregister =  fetchIntercept.register({
  request: function (url, config) {
    return [url, config];
  },

  requestError: function (error) {
    return Promise.reject(error);
  },
  responseError: function (error) {
    return Promise.reject(error);
  },

  response: function (response) {
    if (response.status == 401) {
      Services.refreshToken((res)=>{
        if (res.message == 'success') {
          // if token has been refreshed
          // recall the request again
        }else {
          // login again
        }
      })
    }else {
      return response;
    }
  }
})

The problem is that I've no idea how to recall the same request that passed through the interceptor.. I did some search on this, but couldn't find a way to execute this.

@ChristianUlbrich
Copy link

You are on the right track; I built something similar two years ago. You just have to store the failed request somewhere and simply redispatch it; for this you must correlate the errors with the actual requests made; in the original Angular interceptor stuff, you could get the config of the original request and thus re-construct the actual request.

@lukaszkostrzewa
Copy link

How about instead of retrying when there is 401 HTTP status, simply check earlier (in request interceptor) if token is expired or not? And if it's expired, then refresh the token?

@AnkitaPatelST
Copy link

Hi,
I am trying to make a common interceptor to authorize all my outgoing requests.

My logic is as follows:

All my outgoing requests/API calls passes through the interceptor first to check on my token expiry and in-case the response was un-authorized I make an internal call to refresh the token and update my storage keys with the new values.

Now I need to recall the original request with the new token value, but I can't figure out how to detect the original request that passed through the interceptor.

This is my code :

export  const unregister =  fetchIntercept.register({
  request: function (url, config) {
    return [url, config];
  },

  requestError: function (error) {
    return Promise.reject(error);
  },
  responseError: function (error) {
    return Promise.reject(error);
  },

  response: function (response) {
    if (response.status == 401) {
      Services.refreshToken((res)=>{
        if (res.message == 'success') {
          // if token has been refreshed
          // recall the request again
        }else {
          // login again
        }
      })
    }else {
      return response;
    }
  }
})

The problem is that I've no idea how to recall the same request that passed through the interceptor.. I did some search on this, but couldn't find a way to execute this.

Did find the solution? because I have the same issue

@sai30
Copy link

sai30 commented Oct 27, 2020

I am having the same issue. Not sure how to recall the failed request after refreshing token. Is there any solution for this?

@TheArKaID
Copy link

How if, we intercept in the request, store the url in the storage, and then use the stored url after the refresh token used to get access token ?

@awaissahmed80
Copy link

Here is example of refresh token and recall the original request

const originalRequest = {}
export const interceptor = fetchIntercept.register({    
    request: function (url, config) {
        originalRequest.url = url
        originalRequest.config = config
        return [url, config];
    },
 
    requestError: function (error) {
        // Called when an error occured during another 'request' interceptor call        
        return Promise.reject(error);
    },
 
    response: async function (response) {
        if(response.status === 401)
        {
            const {url, config} = originalRequest
            if(url.includes('token'))
            {
                interceptor()
                return Promise.reject("Session expired");
            }
            else
            {                
                return AppStore.dispatch(AuthActions.refresh_token())
                        .then((data) => {
                            config['headers']['Authorization'] = 'Bearer '+data.token
                            return fetch(url, config)
                        })
                        .catch((error) => {
                            return Promise.reject(error)
                        })                            
            }            
        }
        else
        {
            return response
        }        
    },
 
    responseError: function (error) {
        // Handle an fetch error
        return Promise.reject(error);
    }
});

@vitorcamachoo
Copy link

Here is example of refresh token and recall the original request

const originalRequest = {}
export const interceptor = fetchIntercept.register({    
    request: function (url, config) {
        originalRequest.url = url
        originalRequest.config = config
        return [url, config];
    },
 
    requestError: function (error) {
        // Called when an error occured during another 'request' interceptor call        
        return Promise.reject(error);
    },
 
    response: async function (response) {
        if(response.status === 401)
        {
            const {url, config} = originalRequest
            if(url.includes('token'))
            {
                interceptor()
                return Promise.reject("Session expired");
            }
            else
            {                
                return AppStore.dispatch(AuthActions.refresh_token())
                        .then((data) => {
                            config['headers']['Authorization'] = 'Bearer '+data.token
                            return fetch(url, config)
                        })
                        .catch((error) => {
                            return Promise.reject(error)
                        })                            
            }            
        }
        else
        {
            return response
        }        
    },
 
    responseError: function (error) {
        // Handle an fetch error
        return Promise.reject(error);
    }
});

This will not work if multiple requests were made in parallel. It will use the wrong url and config

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants