AngularJs全局消息服务和身份验证

时间:2013-12-14 06:11:46

标签: angularjs

我有一个消息系统,它有两个方法showclear。我想使用$ http拦截器来处理身份验证,因为我的服务器足够智能,可以根据请求知道用户是否经过身份验证,并通过向我发送状态响应401或{{}来告诉我。 1}}。所以,我的拦截器有这样的东西:

403

对于myModule.factory('statusInterceptor', function($location, MessageService, urlManager){ return { responseError: function(response){ switch(response.status){ ... case 401: case 403: $location.url(urlManager.reverse('Login')); MessageService.show('Dude, you need to log in first.'); break; case 500: break; ... } return response; } }; }); 401响应,它可以正常工作,因为它会按预期显示消息。我遇到的问题是每当用户登录或转到另一条路线时清除消息。我有一个403负责几乎所有事情,其中​​一件事就是MainCtrl。我的想法是视图正在改变到不同的视图,所以我想清除路由开关开头的消息。所以,在$routeChangeStart我有:

MainCtrl

以下是我希望应用程序做出反应的方式:

  1. 用户尝试通过向服务器发送请求而未经过身份验证即可执行某些操作
  2. 服务器以myControllers.controller('MainCtrl', function($scope, MessageService){ $scope.$on('$routeChangeStart', function(){ MessageService.clear(); }); }); 401响应,因为用户未经过身份验证。
  3. 403函数在调用我的responseError方法时触发,在我看来,该方法应该触发$location.url()甚至$routeChangeStart个事件(我已尝试过两者) )。
    • 这应该依次触发我的$locationChangeStart方法并清除之前的任何消息。
  4. 最终用户使用正确的MessageService.clear()消息重定向到登录页面。
  5. 真正发生的事情:

    用户将按预期重定向到登录页面,但不会显示错误消息。在Chrome中设置某些调试点时,我发现"Dude, you need to log in first."会立即被调用,然后是$location.path(),最后是MessageService.show('Dude...')调用。

2 个答案:

答案 0 :(得分:1)

我终于找到了一个解决方案,结果是这样的:

在我的拦截器功能中:

myModule.factory('statusInterceptor', function($rootScope){
    return {
        responseError: function(response){
            switch(response.status){
                ...
                case 401:
                case 403:
                    $rootScope.$broadcast('event:notAuthenticated');
                    break;
                case 500:
                    break;
                ...
            }
            return response;
        }
    };
});

在我的控制器中:

myControllers.controller('MainCtrl', function($scope, $location, MessageService){
    $scope.$on('event:notAuthenticated', function(){
        $location.path(urlManager.reverse('Login'));
        var remove_this_binding = $scope.$on('$routeChangeSuccess', function(){
            messageService.show('Dude, you need to log in first.');
            remove_this_binding();
        });
    });
    $scope.$on('$routeChangeStart', function(){
        messageService.clear();
    });
});

我试图找到一种与$location路径变化相关的回调的角度方式,这是我能想到的最好的方法。如果其他人有更好的解决方案,我会全力以赴。

答案 1 :(得分:1)

也许你喜欢这种问题的方法

http://jsfiddle.net/jYCPQ/1/

module.factory('authenticationInterceptor', function ($q, navigator, MessageService) {
    return {
        responseError: function (response) {
            switch (response.status) {
                case 403:
                    navigator.navigateTo("/login").then(function () {
                        MessageService.show('Dude, you need to log in first.');
                    });
                    return $q.reject(response);
            }
            return response;
        }
    };
});
module.factory("navigator", function ($location, $rootScope, $q) {

    var navigateTo = function (url) {
        var defered = $q.defer();
        $location.url(url);
        var unbind = $rootScope.$on('$routeChangeSuccess', function () {
            defered.resolve();
            unbind();
        })
        return defered.promise;
    }
    return {
        navigateTo: navigateTo
    }
});

问候