【问题标题】:Angular $http Interceptor Opens Multiple Modals When Auth Fails当身份验证失败时,Angular $http 拦截器会打开多个模式
【发布时间】:2015-07-24 14:56:26
【问题描述】:

$auth 失败时,我使用$http interceptor 显示登录模式。这是我的简要设置:

$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抛出多个身份验证失败错误时,拦截器同时打开了多个模态。通常在一页中,我可能有 2-3 次各种服务联系后端 api,当身份验证失败时,所有这些 api 在无效令牌期间返回身份验证失败错误。该拦截器将其作为 3 个 take_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 为真时),我不确定如何返回一个空承诺。

【问题讨论】:

  • 您是否尝试过将“responseError”函数包装在一个服务中,该服务有一个标志来检查模式是否已经显示?
  • 还没有。我现在正试图将modalopen 存储在本地存储中并在 foreach 循环中检查它。不确定该方法是否有效。如果我有任何运气,我会更新。,
  • @XelharK 我认为存储在$rootScope 中比存储在localStorage 中更好。接受您的建议,我想我可以通过在模态打开时将$rootScope.loginProgress 设置为true 来使用$rootScope 作为开关,并且在决定是否打开模态之前,连续的模态会检查这一点。但是,当$rootScope.loginProgress 为真时,我不确定如何向拦截器返回空承诺。我已经用我的服务尝试更新了我的问题。你能帮我看看如何在这里继续吗?
  • 非常感谢您昨天的评论@XelharK 这帮助我最终解决了我的问题。我决定使用http-auth-interceptor,然后在打开登录模式时更改$rootScope.loginProgress。这似乎有效。我已将其添加为答案。如果有更好的方法,请告诉我。非常感谢你的帮助。没有你的评论,我不会继续前进。 :) 干杯!
  • 是的,我就是这么说的。抱歉没有回答,我周末不在。无论如何,我认为你可以将这一切都包装在一个服务中,并在你的 conf 文件中使用一个简单的配置行来进行绑定,这样你就有了最大的模块化 :)

标签: angularjs angular-http angular-http-interceptors angular-http-auth


【解决方案1】:

为了解决我的问题,我现在使用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() 是打开登录模式的服务。

【讨论】:

    猜你喜欢
    • 2020-06-06
    • 1970-01-01
    • 2017-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-06
    • 1970-01-01
    相关资源
    最近更新 更多