У меня есть приложение angular, которое иногда выполняет несколько запросов $http.get для каждого состояния. Приложение использует JWT для авторизации пользователя с обновляющими токенами. Сервер API отправляет 401
при каждом неудавшемся провале из-за ошибки auth.
Я сделал http interceptor
, который запрашивает новый токен с токеном обновления при ошибках 401 и после этого отправляет исходный запрос.
Проблема в том, что если состояние делает, например, 2 $http.get-запросы, и оба получают ответ 401, я дважды обновляю токен доступа. Очевидно, я хочу только один раз обновить токен, но я все еще хочу повторно отправить BOTH неудачные запросы.
Является ли это достижимым, и если да, то как?
app.factory('AuthInterceptor', function($q, $injector, RESOURCE_URL, API_BASE, authService) {
return {
request: function(config) {
config.headers = config.headers || {};
if (authService.getAccessToken()) {
if (config.url.substring(0, RESOURCE_URL.length) !== RESOURCE_URL) {
config.headers.Authorization = 'Bearer ' + authService.getAccessToken();
}
}
return config;
},
responseError: function(response) {
switch (response.status) {
case 401:
var deferred = $q.defer();
$injector.get("$http").post(API_BASE + '/api/auth/refresh', {refreshtoken: authService.getRefreshToken()}).then(function(r) {
if (r.data.data.accesstoken && r.data.data.refreshtoken && r.data.data.expiresin) {
authService.setAccessToken(r.data.data.accesstoken);
authService.setRefreshToken(r.data.data.refreshtoken);
authService.setExpiresIn(r.data.data.expiresin);
$injector.get("$http")(response.config).then(function(resp) {
deferred.resolve(resp);
},function(resp) {
deferred.reject();
});
} else {
deferred.reject();
}
}, function(response) {
deferred.reject();
authService.clear();
$injector.get("$state").go('guest.login');
return;
});
return deferred.promise;
break;
default:
authService.clear();
$injector.get("$state").go('guest.login');
break;
}
return response || $q.when(response);
}
};
});