I have a backend with jwt auth and I want to handle expired tokens.
The following flow is required :
- Make a request with token attached (and expect a promise)
- If it goes fine, then just return the promise (and the then/fail method of the caller are executed)
- If it fails (with 401 unauthorized) then a request is made to refresh the token and token is updated locally
- If step 3 is successful, return a promise for original request
- If step 3 fails with 401 (token cannot be refreshed) error redirect to login page
Problem : In step 4, the original function is called (again) but the caller's then/fail method are not triggered.
Following is my method to append jwt token to the url and send the http request :
var AuthenticatedRequest = function(url, data, method) {
return (function tryRequest(){
console.log('calling tryRequest');
return reqwest({
url: ApiUtil.tokenUrlTo(url),
method: method,
crossOrigin: true,
type: 'json',
data: data
})
.fail(function(err) {
if (err.status === 401) {
return post('/auth/refresh-token')
.then(function(response){
console.log('assume token set');
//code to update token locally
})
.then(tryRequest)
.fail(function(err){
// Can't refresh token. Send to login page
})
;
}
})
;
})();
};
And here is the caller :
fetchModules: function() {
get('/admin/modules')
.then(function(response) {
Actions.modulesFetchSuccess(response.collection);
})
.fail(function(err) {
Actions.modulesFetchError(ApiUtil.errorArrayForResponse(err));
})
;
},
Now if I get a 401 because the token expired, I trigger a new cycle to refresh the token as suggested in this question Restart a promise after fail.
Note : post
and get
function is just a wrapper around the AuthenticatedRequest
function with method set to POST
or GET
.
The AuthenticatedRequest
function returns a promise, and if the token is not expired, this runs fine, however, when the token is expired, I get an error in my console and new token is fetched and the function is called again, screenshot of my console - https://i.stack.imgur.com/hJdId.png
But the then
method of fetchModules
does not get fired after token is updated. What am I doing wrong ?
Possible Duplicates :
- AngularJS - Handling refresh token?
- How to resend request when not authorized
- Restart a promise after fail
Update September 13, 2015
@Bergi's answer worked when I replaced reqwest.js
and used q.js
with vanilla ajax as show in this gist