簡體   English   中英

刷新令牌刷新jwt后如何刷新數據

[英]How to refresh data after refresh token refreshes 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返回並且我可以得到一個下拉菜單刷新,但我在頁面上丟失了任何狀態(例如選擇下拉列表),如下所示。

authService.refreshToken().then(function() {
var $state = $injector.get('$state');
$state.reload();
});

回到繪圖板!

嘗試在$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返回一個使用函數參數返回的promise完成的promise,因此我們可以方便地返回$ timeout中包含的$ http調用。

謝謝。

我想你可能想改變你的方式。 解決這個問題的一種方法是將$ 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;
            }
        };
    }
]);

https://github.com/tjoudeh/AngularJSAuthentication/blob/master/AngularJSAuthentication.Web/app/services/authInterceptorService.js復制了幾乎1比1。

這個透明地處理所有請求並在必要時刷新它們。 它在刷新令牌過期時注銷用戶,並通過正確拒絕它們將錯誤傳遞給控制器​​。 但是,它似乎不適用於多個飛行請求,當我在我的系統中獲得一個用例時,我會調查它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM