Как обновить данные после обновления Токен обновляет jwt
Я пытался заставить мой токен обновления работать некоторое время, и я надеюсь, что я близок. Мой токен обновляет и запускает последующий вызов 200 для любого вызова, вызвавшего 401, но мои данные на моей странице не обновляются.
когда токен доступа истекает, происходит следующее:
после 401 GetListofCompanyNames возвращает 200 со списком имен, используя правильный обновленный маркер доступа. Однако, мой выпадающего не обновляется.
мой перехватчик:
app.factory('authInterceptorService',['$q', '$location', 'localStorageService', '$injector', function($q, $location, localStorageService, $injector) {
return {
request: function(config) {
config.headers = config.headers || {};
var authData = localStorageService.get('authorizationData');
if (authData) {
config.headers.Authorization = 'Bearer ' + authData.token;
}
return config;
},
responseError: function(rejection) {
//var promise = $q.reject(rejection);
var authService = $injector.get('authService');
if (rejection.status === 401) {
// refresh the token
authService.refreshToken().then(function() {
// retry the request
var $http = $injector.get('$http');
return $http(rejection.config);
});
}
if (rejection.status === 400) {
authService.logOut();
$location.path('/login');
}
return $q.reject(rejection);
}
};
}
]);
мое заявление о возврате на отказ 401 выглядит подозрительным здесь, но я не уверен, чем его заменить. Таким образом, мой вопрос: Как я могу заставить свою страницу обновить данные, когда я делаю новый вызов?
обновление:
Это позволяет мне пройти, когда 200 возвращается, и я могу получить раскрывающийся список для обновления, но я теряю любое состояние на странице (ex. выбранное выпадающее меню) с под.
authService.refreshToken().then(function() {
var $state = $injector.get('$state');
$state.reload();
});
назад к чертежной доске!
3 ответов
попробуйте поставить свой повторный вызов в $timeout
, Она должна работать.
вот обновленный код:
app.factory('authInterceptorService',['$q', '$location', 'localStorageService', '$injector', function($q, $location, localStorageService, $injector) {
return {
request: function(config) {
config.headers = config.headers || {};
var authData = localStorageService.get('authorizationData');
if (authData) {
config.headers.Authorization = 'Bearer ' + authData.token;
}
return config;
},
responseError: function(rejection) {
//var promise = $q.reject(rejection);
var authService = $injector.get('authService');
if (rejection.status === 401) {
// refresh the token
authService.refreshToken().then(function() {
// retry the request
return $timeout(function() {
var $http = $injector.get('$http');
return $http(rejection.config);
}});
}
if (rejection.status === 400) {
authService.logOut();
$location.path('/login');
}
return $q.reject(rejection);
}
};
}
]);
$ timeout возвращает обещание, которое завершается тем, что возвращается от параметра функции, поэтому мы можем удобно как раз возвратить $ http-вызов, обернутый в $ timeout.
спасибо.
Я думаю, вы, возможно, захотите изменить то, как вы это делаете. Один из способов сделать это - ввести $rootScope в ваш authInterceptorService
а затем, как только вы успешно обновите токен, вызовите что-то вроде $rootScope.broadcast('tokenRefreshed')
.
Я не совсем знаю, как вы настроили представление и контроллер, который обрабатывает ваше выпадающее меню, но я бы настроил слушателя для этого 'tokenRefreshed'
событие. Отсюда вы можете сделать еще один вызов GetListofCompanyNames
. Если вы делаете это таким образом, вы можете легко контролировать и обеспечивать что модель обновляется.
мое окончательное решение:
app.factory('authInterceptorService', ['$q', '$location', 'localStorageService', '$injector', function($q, $location, localStorageService, $injector) {
var $http;
var retryHttpRequest = function(config, deferred) {
$http = $http || $injector.get('$http');
$http(config).then(function(response) {
deferred.resolve(response);
},
function(response) {
deferred.reject(response);
});
}
return {
request: function(config) {
config.headers = config.headers || {};
var authData = localStorageService.get('authorizationData');
if (authData) {
config.headers.Authorization = 'Bearer ' + authData.token;
}
return config;
},
responseError: function(rejection) {
var deferred = $q.defer();
if (rejection.status === 401) {
var authService = $injector.get('authService');
authService.refreshToken().then(function() {
retryHttpRequest(rejection.config, deferred);
},
function () {
authService.logOut();
$location.path('/login');
deferred.reject(rejection);
});
} else {
deferred.reject(rejection);
}
return deferred.promise;
}
};
}
]);
скопировано почти 1 для 1 из https://github.com/tjoudeh/AngularJSAuthentication/blob/master/AngularJSAuthentication.Web/app/services/authInterceptorService.js .
этот прозрачно обрабатывает все запросы и обновляет их при необходимости. Он выходит из системы пользователей, когда токен обновления истек и передает ошибки контроллерам, правильно отклоняя их. Однако он, похоже, не работает с несколькими в запросах на полет я рассмотрю это, когда получу прецедент для него в своей системе.