For my problem, the best way I found was to create an "Interceptor". Below is the code developed. Hope it helps someone.
.factory('settingsService', [function() {
var settingsServiceFactory = {};
var _getSettings = function(requestData) {
return {
url: requestData.url,
dataType: requestData.dataType || "json",
data: requestData.data || {},
headers: requestData.headers || {
"Content-Type": "application/json; charset=utf-8"
},
async: requestData.async || false,
cache: requestData.cache || false,
success: requestData.success || {},
error: requestData.error || {},
complete: requestData.complete || {},
fail: requestData.fail || {}
};
};
settingsServiceFactory.getSettings = _getSettings;
return settingsServiceFactory;
}])
.factory('authInterceptorService', ['$log', '$q', '$location', '$localStorage', '$injector', 'settingsService',
function($log, $q, $location, $localStorage, $injector, settingsService) {
var inFlightAuthRequest = null;
var authInterceptorServiceFactory = {};
var _request = function(config) {
config.headers = config.headers || {};
var authData = $localStorage.authorizationData;
if (authData) {
$log.log('[_request -> access_token]: ', authData.access_token);
config.headers.Authorization = 'Bearer ' + authData.access_token;
}
return config;
};
var _responseError = function(response) {
$log.warn('[_responseError -> response]: ', response);
switch (response.status) {
case 401:
if (!$localStorage.authorizationData) {
$location.path('/login');
return;
}
var deferred = $q.defer();
if (!inFlightAuthRequest) {
var requestData = {
url: $localStorage.serviceBase + '/token',
data: {
refresh_token: $localStorage.authorizationData.refresh_token,
grant_type: "refresh_token"
}
};
var settings = settingsService.getSettings(requestData);
settings.method = "POST";
inflightAuthRequest = $injector.get("$http")(settings);
}
inflightAuthRequest.then(function(r) {
inflightAuthRequest = null;
if (r.data && r.data.access_token && r.data.refresh_token) {
$localStorage.authorizationData = r.data;
$log.warn('[new token]: ', $localStorage.authorizationData.access_token);
$injector.get("$http")(response.config).then(function(resp) {
deferred.resolve(resp);
}, function(resp) {
deferred.reject();
});
} else {
deferred.reject();
}
}, function(response) {
inflightAuthRequest = null;
deferred.reject();
delete $localStorage.authorizationData;
$location.path('/login');
return;
});
return deferred.promise;
}
return response || $q.when(response);
};
authInterceptorServiceFactory.request = _request;
authInterceptorServiceFactory.responseError = _responseError;
return authInterceptorServiceFactory;
}
]);