I have a simple (half finished) http interceptor that appends a Bearer
token (stored in $window.sessionsStorage
) to the header so that REST API requests can be authenticated:
function accessTokenHttpInterceptor($window, $http) {
// Try to get token details from sessionStorage
var accesstoken=$window.sessionStorage.getItem('userInfo-accesstoken');
var refreshtoken=$window.sessionStorage.getItem('userInfo-refreshtoken');
var tokenexpiry=$window.sessionStorage.getItem('userInfo-tokenexpiry');
return {
request: function($config) {
// Check if the access token, refresh token and expiry date exists:
if (accesstoken == undefined || refreshtoken == undefined || tokenexpiry == undefined) {
console.log('Missing token details');
// TODO REDIRECT TO LOGIN PAGE
}
// We have an access token. Has it expired?
var expiry = new Date($window.sessionStorage['userInfo-tokenexpiry'])
var now = new Date
if (now > expiry ) {
console.log('Token expired');
// TODO REFRESH THE TOKEN
};
// Set the authorization header
$config.headers['Authorization'] = 'Bearer ' + accesstoken;
return $config;
},
};
}
accessTokenHttpInterceptor.$inject=['$window'];
function httpInterceptorRegistry($httpProvider) {
$httpProvider.interceptors.push('accessTokenHttpInterceptor');
}
angular
.module('myApp')
.config(httpInterceptorRegistry)
.factory('accessTokenHttpInterceptor', accessTokenHttpInterceptor)
As you can see, I am able to see if the token has expired prior to making the call to the API.
Can anybody help me with how to refresh the token prior to making the actual API request? I would think that making another $http request would be intercepted again and end up in an infinite loop. The token is refreshed by making a POST request to the API, where the refresh token is passed as a parameter, not in the Authorization header like other API requests.
You could check the url of the request to prevent an infinite loop. Also instead of returning the config directly you could return a promise that resolves with it so you can wait until you have a valid token. e.g.
{
request: function(config) {
if(config.url != 'my/refresh/url') {
var promiseToHaveValidToken;
var expiry = new Date($window.sessionStorage['userInfo-tokenexpiry']);
var now = new Date();
if (now > expiry ) {
promiseToHaveValidToken = $http.get('my/refresh/url').then(function (response) {
return response.data.token;
});
} else {
promiseToHaveValidToken = $q.resolve(sessionStorage['userInfo-accesstoken']);
}
return promiseToHaveValidToken.then(function (token) {
config.headers['Authorization'] = 'Bearer ' + token;
return config;
});
}
}
}