Как обновить данные после обновления Токен обновляет jwt

Я пытался заставить мой токен обновления работать некоторое время, и я надеюсь, что я близок. Мой токен обновляет и запускает последующий вызов 200 для любого вызова, вызвавшего 401, но мои данные на моей странице не обновляются.

когда токен доступа истекает, происходит следующее:

enter image description here

после 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 .

этот прозрачно обрабатывает все запросы и обновляет их при необходимости. Он выходит из системы пользователей, когда токен обновления истек и передает ошибки контроллерам, правильно отклоняя их. Однако он, похоже, не работает с несколькими в запросах на полет я рассмотрю это, когда получу прецедент для него в своей системе.