Reputation: 1054
I am very weak in javascript but I think I understand what's going wrong. Just not fluent enough to know how to fix it or even how to correctly write it. I have a VueJS app that sends requests to an API with an access_token
. When that access_token
expiries it sends a refresh_token
to the API and gets a new access_token
. I want it to then redo the request it was running when it expired. Using the code below I get strange behavior. When it hits the 401
I can see it access the /token
endpoint and get a new access_token
however the next call to /brewery
is using the old access_token
. This happens about 5 times before a call to /brewery
finally uses the new access_token
and the loop stops. My guess is that when I call this.loaded()
the call to auth.refreshToken()
hasn't finished yet?
loaded(access_token){
var headers;
if(access_token)
{
headers = { 'Authorization': 'Bearer ' + access_token }
}
else
{
headers = auth.getAuthHeader();
}
axios.get(this.getBaseUrl + '/brewery/', { headers })
.then((response) => {
this.breweries = response.data.data.slice(0);
})
.catch((error) => {
if(error.response.status == 401)
{
console.log("error 401");
var new_access_token = auth.refreshToken();
this.loaded(new_access_token);
}
});
}
Auth class
refreshToken(context) {
var token =
{
refresh_token: localStorage.getItem('refresh_token'),
grant_type: 'refresh_token'
};
token = querystring.stringify(token);
axios.post(LOGIN_URL, token)
.then((response) => {
localStorage.removeItem('access_token');
localStorage.setItem('access_token', response.data.access_token);
this.checkLoggedIn();
if(!this.isAdmin())
{
context.error = "You are not an admin user";
}
return response.data.access_token;
})
.catch(function (error) {
if(error.response){
if(error.response.status == 400)
{
console.log(error.response.data);
context.error = error.response.data;
}
}
})
}
Upvotes: 0
Views: 854
Reputation: 910
This looks like promise chaining/structure issue. To make the call to this.loaded
occur after the call to auth.refreshToken
has completed you should make the refreshToken
method return a promise. Specifically, it should return the axios.post
call. That axios.post
call, when successful is actually executing this line return response.data.access_token;
and resolving the token. Now when you make a call to auth.refreshToken
you should append a then
block like so:
auth.refreshToken().then((token) => { this.loaded(token) })
Without structuring this code in a synchronous manner, you're going to get multiple calls to this.loaded
because each one will fail with a stale token... or at the least an undefined token.
Upvotes: 1