I have an interceptor like this
axios.interceptors.response.use(undefined, err=> {
const error = err.response;
console.log(error);
if (error.status===401 && error.config && !error.config.__isRetryRequest) {
return axios.post(Config.oauthUrl + '/token', 'grant_type=refresh_token&refresh_token='+refreshToken,
{ headers: {
'Authorization': 'Basic ' + btoa(Config.clientId + ':' + Config.clientSecret),
'Content-Type': 'application/x-www-form-urlencoded,charset=UTF-8'
}
})
.then(response => {
saveTokens(response.data)
error.config.__isRetryRequest = true;
return axios(error.config)
})
}
})
And everything is working, but if I have like in my case 4 API calls on one React Component, and this error happens the same code will be run 4 times, meaning 4 times I will send my refresh token and get the auth token, and I would want to run it only once obviously
I have an interceptor like this
axios.interceptors.response.use(undefined, err=> {
const error = err.response;
console.log(error);
if (error.status===401 && error.config && !error.config.__isRetryRequest) {
return axios.post(Config.oauthUrl + '/token', 'grant_type=refresh_token&refresh_token='+refreshToken,
{ headers: {
'Authorization': 'Basic ' + btoa(Config.clientId + ':' + Config.clientSecret),
'Content-Type': 'application/x-www-form-urlencoded,charset=UTF-8'
}
})
.then(response => {
saveTokens(response.data)
error.config.__isRetryRequest = true;
return axios(error.config)
})
}
})
And everything is working, but if I have like in my case 4 API calls on one React Component, and this error happens the same code will be run 4 times, meaning 4 times I will send my refresh token and get the auth token, and I would want to run it only once obviously
Share Improve this question asked Sep 15, 2016 at 10:52 high incompetancehigh incompetance 2,6584 gold badges20 silver badges28 bronze badges2 Answers
Reset to default 15I think you can queue authentication requests with something like:
let authTokenRequest;
// This function makes a call to get the auth token
// or it returns the same promise as an in-progress call to get the auth token
function getAuthToken() {
if (!authTokenRequest) {
authTokenRequest = makeActualAuthenticationRequest();
authTokenRequest.then(resetAuthTokenRequest, resetAuthTokenRequest);
}
return authTokenRequest;
}
function resetAuthTokenRequest() {
authTokenRequest = null;
}
And then in your interceptor...
axios.interceptors.response.use(undefined, err => {
const error = err.response;
if (error.status===401 && error.config && !error.config.__isRetryRequest) {
return getAuthToken().then(response => {
saveTokens(response.data);
error.config.__isRetryRequest = true;
return axios(error.config);
});
}
});
I hope this helps you ;)
Have you considered a throttle/debounce wrapper for the request? lodash has both built-in. Here's a good example of the two. Albeit in underscore but same difference.
http://jsfiddle.net/missinglink/19e2r2we/
...maybe something like this for your case?
axios.interceptors.response.use(undefined, err=> {
const error = err.response;
console.log(error);
if (error.status===401 && error.config && !error.config.__isRetryRequest) {
return _.debounce(axios.post(Config.oauthUrl + '/token', 'grant_type=refresh_token&refresh_token='+refreshToken,
{ headers: {
'Authorization': 'Basic ' + btoa(Config.clientId + ':' + Config.clientSecret),
'Content-Type': 'application/x-www-form-urlencoded,charset=UTF-8'
}
})
.then(response => {
saveTokens(response.data)
error.config.__isRetryRequest = true;
return axios(error.config)
}), 1000)
}
})
might be better like this though?
axios.interceptors.response.use(undefined, _.debounce(