We have successfully incorporated token authorization with refresh token logic into our application. While everything is functioning as expected, we are looking to enhance the retry mechanism for requests that fail due to token expiration. The entire process is managed within the Interceptor module of our codebase. Below is a snippet of the relevant code:
a.service('APIInterceptor', function ($q, $rootScope, $location, $window, $injector) {
var service = this;
var $http;
var refreshTokenInProcess = false;
executeRequest = function (config) {
var accessToken = $window.localStorage.getItem('token');
if (accessToken != 'null') {
config.headers.authorization = "bearer " + accessToken;
}
lastRequest = config;
return config;
};
service.request = function (config) {
return executeRequest(config);
};
var tokenRefreshing = function () {
var deferred = $q.defer();
// Implementing a one-time token refresh in case of multiple failed requests
if (refreshTokenInProcess == false) {
var refreshToken = $window.localStorage.getItem('refresh_token');
var clientId = $window.localStorage.getItem('client_id');
var apiUrl = $window.localStorage.getItem('apiUrl');
var param = "grant_type=refresh_token&refresh_token=" + refreshToken + "&client_id=" + clientId;
$http = $http || $injector.get('$http');
$http.post(apiUrl + 'token', param, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).
then(function (success) {
$window.localStorage.setItem('token', success.data.access_token);
$window.localStorage.setItem('refresh_token', success.data.refresh_token);
$window.localStorage.setItem('client_id', "web");
$window.localStorage.setItem('expires', success.data[".expires"]);
deferred.resolve(success);
refreshTokenInProcess = false;
}, function (err) {
deferred.reject(err);
});
}
else
deferred.resolve();
refreshTokenInProcess = true;
return deferred.promise;
};
service.responseError = function (response) {
if (response.status === 406 && response.data === "Unauthenticated Token.") {
// Retry logic
tokenRefreshing().then(function () {
return $http(executeRequest(response.config)).then(function (data) {
if (data)
response.config.callerController(data.data);
})
});
}
};
While the system functions properly with individual failed requests, we have observed an issue where retries start looping when multiple failed requests occur over longer periods. We have attempted to resolve this by using the refreshTokenInProcess flag, but unsuccessful so far. Any suggestions or design patterns you can recommend would be greatly appreciated.
Thank you