Angular $http 拦截器在 Auth 失败时打开多个模式
Angular $http Interceptor Opens Multiple Modals When Auth Fails
我正在使用 $http interceptor
在 $auth
失败时显示登录模式。这是我的简要设置:
$provide.factory('modalWhenLoggedOut', ['$q', '$injector', '$rootScope',
function($q, $injector, $rootScope) {
return {
responseError: function(rejection) {
// $injector.get to fix circular dependency error
var loginModal = $injector.get('LoginModalService');
var $http = $injector.get('$http');
var $state = $injector.get('$state');
// Check for reasons instead of status code
var rejectionReasons = ['token_not_provided', 'token_expired', 'token_absent', 'token_invalid'];
// Loop through each rejection reason and redirect
angular.forEach(rejectionReasons, function(value, key) {
if(rejection.data.error === value) {
// Show the login modal
var deferred = $q.defer();
loginModal()
.then(function () {
deferred.resolve( $http(rejection.config) );
})
.catch(function () {
$state.go('index');
deferred.reject(rejection);
});
return deferred.promise;
}
});
return $q.reject(rejection);
}
}
}]);
// Push the new factory onto the $http interceptor array
$httpProvider.interceptors.push('modalWhenLoggedOut');
以上代码运行良好。但我遇到的问题是,当 api 抛出多个身份验证失败错误时,拦截器同时打开多个模式。通常在 1 页中,我可能有 2-3 次联系后端 api 的各种服务,并且当身份验证失败时,所有这些 api return 在无效令牌期间出现身份验证失败错误。此拦截器将其拾取为 3 taken_invalid 错误,并显示 3 个登录模式 1 彼此重叠。我该如何防止这种情况?
无论发生多少次身份验证失败,如何确保拦截器只显示 1 个登录模式?
我的服务看起来像这样:
.service('LoginModalService', ['$modal', '$rootScope',
function($modal, $rootScope) {
function updateRootScope() {
$rootScope.loginProgress = false;
}
if ($rootScope.loginProgress = false) {
return function() {
var instance = $modal.open({
templateUrl: rootPath + 'views/partials/LoginModalTemplate.html',
controller: 'LoginModalCtrl'
})
return instance.result.then(updateRootScope);
};
}
}])
在服务中,我尝试使用 $rootScope.loginProgress
作为开关来确定是否打开了登录模式。但是,如果模式已经打开(当 $rootScope.loginProgress
为真时),我不确定如何 return 一个空的承诺。
为了解决我的问题,我现在使用 http-auth-interceptor
拦截器,然后根据登录模式打开状态更改 $rootScope.loginProgress
。由于多个 401 而打开的连续模式将检查此登录模式状态,然后决定是否打开模式。使用 http-auth-interceptor
,我可以通过观察 'event:auth-loginRequired'
添加开关。这是我使用的代码:
scope.$on('event:auth-loginRequired', function() {
if(!$rootScope.loginProgress) {
$rootScope.loginProgress = true;
LoginModalService()
.then(function () {
authService.loginConfirmed();
$rootScope.loginProgress = false;
})
.catch(function () {
authService.loginCancelled();
$rootScope.loginProgress = false;
});
}
});
其中 LoginModalService()
是打开登录模式的服务。
我正在使用 $http interceptor
在 $auth
失败时显示登录模式。这是我的简要设置:
$provide.factory('modalWhenLoggedOut', ['$q', '$injector', '$rootScope',
function($q, $injector, $rootScope) {
return {
responseError: function(rejection) {
// $injector.get to fix circular dependency error
var loginModal = $injector.get('LoginModalService');
var $http = $injector.get('$http');
var $state = $injector.get('$state');
// Check for reasons instead of status code
var rejectionReasons = ['token_not_provided', 'token_expired', 'token_absent', 'token_invalid'];
// Loop through each rejection reason and redirect
angular.forEach(rejectionReasons, function(value, key) {
if(rejection.data.error === value) {
// Show the login modal
var deferred = $q.defer();
loginModal()
.then(function () {
deferred.resolve( $http(rejection.config) );
})
.catch(function () {
$state.go('index');
deferred.reject(rejection);
});
return deferred.promise;
}
});
return $q.reject(rejection);
}
}
}]);
// Push the new factory onto the $http interceptor array
$httpProvider.interceptors.push('modalWhenLoggedOut');
以上代码运行良好。但我遇到的问题是,当 api 抛出多个身份验证失败错误时,拦截器同时打开多个模式。通常在 1 页中,我可能有 2-3 次联系后端 api 的各种服务,并且当身份验证失败时,所有这些 api return 在无效令牌期间出现身份验证失败错误。此拦截器将其拾取为 3 taken_invalid 错误,并显示 3 个登录模式 1 彼此重叠。我该如何防止这种情况?
无论发生多少次身份验证失败,如何确保拦截器只显示 1 个登录模式?
我的服务看起来像这样:
.service('LoginModalService', ['$modal', '$rootScope',
function($modal, $rootScope) {
function updateRootScope() {
$rootScope.loginProgress = false;
}
if ($rootScope.loginProgress = false) {
return function() {
var instance = $modal.open({
templateUrl: rootPath + 'views/partials/LoginModalTemplate.html',
controller: 'LoginModalCtrl'
})
return instance.result.then(updateRootScope);
};
}
}])
在服务中,我尝试使用 $rootScope.loginProgress
作为开关来确定是否打开了登录模式。但是,如果模式已经打开(当 $rootScope.loginProgress
为真时),我不确定如何 return 一个空的承诺。
为了解决我的问题,我现在使用 http-auth-interceptor
拦截器,然后根据登录模式打开状态更改 $rootScope.loginProgress
。由于多个 401 而打开的连续模式将检查此登录模式状态,然后决定是否打开模式。使用 http-auth-interceptor
,我可以通过观察 'event:auth-loginRequired'
添加开关。这是我使用的代码:
scope.$on('event:auth-loginRequired', function() {
if(!$rootScope.loginProgress) {
$rootScope.loginProgress = true;
LoginModalService()
.then(function () {
authService.loginConfirmed();
$rootScope.loginProgress = false;
})
.catch(function () {
authService.loginCancelled();
$rootScope.loginProgress = false;
});
}
});
其中 LoginModalService()
是打开登录模式的服务。