AngularJs全局消息服务和身份验证
我有一个消息系统,它有两种方法AngularJs全局消息服务和身份验证,angularjs,Angularjs,我有一个消息系统,它有两种方法show和clear。我想使用$http拦截器来处理身份验证,因为我的服务器足够聪明,可以知道每个请求是否对用户进行了身份验证,并通过向我发送401或403的状态响应来告诉我。我的拦截器是这样的: myModule.factory('statusInterceptor', function($location, MessageService, urlManager){ return { responseError: function(resp
show
和clear
。我想使用$http拦截器来处理身份验证,因为我的服务器足够聪明,可以知道每个请求是否对用户进行了身份验证,并通过向我发送401
或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
中,我有:
myControllers.controller('MainCtrl', function($scope, MessageService){
$scope.$on('$routeChangeStart', function(){
MessageService.clear();
});
});
以下是我期望应用程序的反应方式:
401
或403
响应,因为用户未经身份验证$location.url()
方法将触发responseError
函数,在我看来,该方法应该触发$routeChangeStart
,甚至$locationChangeStart
事件(我已经尝试了这两种方法)。
- 这将依次触发我的
方法并清除以前的任何消息MessageService.clear()
“Dude,您需要先登录。”
消息用户将按预期重定向到登录页面,但不会显示错误消息。在Chrome中设置某些调试点时,我看到调用
$location.path()
后紧接着调用MessageService.show('Dude…')
,最后是MessageService.clear()
调用。我终于找到了一个解决方案,结果是这样的:
在我的拦截器函数中:
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
的路径更改相关联,这是我能想到的最好的方法。如果其他人有更好的解决方案,我洗耳恭听。也许你喜欢这种解决问题的方法
关于我喜欢使用$q承诺。我不知道除了请求/响应事件之外,您还可以使用它。那么,$q只是一种更简单/更整洁的回调方式?
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
}
});