AngularJS拦截重试请求

AngularJS interceptor retry request

你好,我正在开发一个 Angular 应用程序,我在尝试重试在 http 拦截器中发出的最新请求时遇到了一些问题。 我有这个拦截器用于对每个请求进行身份验证验证,并且我在令牌过期的响应中也有它。问题是,当我的令牌过期时,我需要为它触发刷新令牌以获得新的访问权限,如果它成功,那么我会重试拦截的请求。

一切正常。但是...我有多个被拒绝的 401 呼叫,当我尝试登录时(您可以看到 console.log 消息)。似乎只有第一个被拒绝的调用才会触发刷新令牌请求。什么是最好的方法或可以使其发挥作用的方法?提早。

var _responseError = function (rejection) {
    if (rejection.status === 401) {
        var authService = $injector.get('authService');
        var state = $injector.get('$state');
        var http = $injector.get('$http');
        var deferred = $q.defer();
        if (rejection.data && rejection.data.ErrorCode == errorCodes.missingRole){
            return $q.reject(rejection);
        }
        //var authData = localStorageService.get(authConstant.cookieName);
        var authData = authService.getAuth();
        if (authData) {
               return authService.refreshToken().then(function (response) {
                       console.log("call is: ", rejection);
                    if (response.access_token){
                        //Todo: find a method to resend last request;
                        return http(rejection.config);
                    }
                },
                function (err) {
                    state.go('app.login');
                    return $q.reject(rejection);
                });
        }
        authService.logOut();
        state.go('app.login');
    }
    return $q.reject(rejection);
};

有类似的问题。我的代码有点不同,但思路是一样的,试试这个

var deferred = $q.defer();
authService.refreshToken().then(function () {
        $http(errorResponse.config).then(deferred.resolve, deferred.reject);
    }, function () {
        authService.logOut().then(deferred.reject);
    });

return deferred.promise;

我已经设法使用 http 缓冲区来存储所有未来被拒绝的后端调用来解决这个问题。 缓冲区代码在这里: https://github.com/witoldsz/angular-http-auth/blob/master/src/http-auth-interceptor.js

我稍微修改了一下使其正常工作,这是修改后的版本:

angular.module('authModule').factory('httpBufferService', ['$injector', function($injector) {
/** Holds all the requests, so they can be re-requested in future. */
var buffer = [];
var doAction=false;
/** Service initialized later because of circular dependency problem. */
var $http;

function retryHttpRequest(config, deferred) {
    function successCallback(response) {
        deferred.resolve(response);
    }
    function errorCallback(response) {
        deferred.reject(response);
    }
    $http = $http || $injector.get('$http');
    $http(config).then(successCallback, errorCallback);
}
var bufferData = {
    getItems:function (){
        return buffer;
    },
        /**
         * Appends HTTP request configuration object with deferred response attached to buffer.
         */
    append: function(config, deferred) {
        buffer.push({
            config: config,
            deferred: deferred
        });
    },

    /**
     * Abandon or reject (if reason provided) all the buffered requests.
     */
    rejectAll: function(reason) {
        if (reason) {
            for (var i = 0; i < buffer.length; ++i) {
                buffer[i].deferred.reject(reason);
            }
        }
        buffer = [];
    },
    clean:function(){
        buffer = [];
        doAction = false;
    },
    /**
     * Retries all the buffered requests clears the buffer.
     */
    retryAll: function() {
        if (!doAction){
            doAction = true;
            for (var i = 0; i < buffer.length; ++i) {
                retryHttpRequest(buffer[i].config, buffer[i].deferred);
            }
            bufferData.clean();
        }

    }
};
return bufferData;
}]);

这是实现:

var authData = authService.getAuth();
httpBuffer.append(rejection.config,defer);
if (httpBuffer.getItems().length>1){
    return defer.promise;
}
if (authData) {
   return authService.refreshToken().then(function (response) {
        if (response.access_token){
            httpBuffer.retryAll();
            return defer.promise;            
        }
    },
    function (err) {        
        httpBuffer.clean();
        authService.logOut();        
        return $q.reject(rejection);
    });
}
httpBuffer.clean();