Angularjs 使用(异步)$http结果(同步)检查路由上的权限
我正在尝试检查AngularJS应用程序中的路由权限。路由由angular ui路由器处理 我的路由和每个路由的权限定义如下:Angularjs 使用(异步)$http结果(同步)检查路由上的权限,angularjs,angular-ui-router,Angularjs,Angular Ui Router,我正在尝试检查AngularJS应用程序中的路由权限。路由由angular ui路由器处理 我的路由和每个路由的权限定义如下: angular.module('my_app') .config(function ($stateProvider, $urlRouterProvider) { $stateProvider .state('root', { abstract: true, templateUrl: 'conte
angular.module('my_app')
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('root', {
abstract: true,
templateUrl: 'content.html',
resolve: {
user_info: function (UserService) {
return UserService.user_info();
}
}
})
.state('root.some_page', {
url: '/',
templateUrl: 'some_page.html',
controller: 'home',
data: {
roles: ['some_right', 'some_other_right]
}
});
}
然后检查权限,如下所示:
[...].run(function ($rootScope, $state, UserService) {
$rootScope.$on('$stateChangeStart',
function (event, toState) {
if (!!toState.data) {
var required_roles = toState.data.roles;
if (!UserService.has_permission_in(required_roles)) {
event.preventDefault();
$state.go('root.access_forbidden');
}
}
});
});
现在一切都好。我的问题是解决用户权限问题。它们由后端提供,并使用$http.get(…)
获取。由于$http
服务返回承诺,因此在触发$stateChangeStart
事件时,它并不总是有结果
当应用程序处于“热”状态时,它是“好”的,但是如果我进入一个受保护的页面,它就会失败(数据还没有准备好)。我无法“等待”承诺
对路由进行访问控制的“好”方法是什么?在受保护州的定义中:
.state('root.some_page', {
url: '/',
templateUrl: 'some_page.html',
controller: 'home',
resolve: {
access: function($http, $state){ //Note: you can inject your own services/factories too
var requiredPermissions = ['some_right', 'some_other_right'];
return $http.get(...).then(function(response){
var permissions = response.data.permissions;
var granted = permissions.reduce((prev,curr) => requiredPermissions.indexOf(curr) > -1 || prev, false);
if(!granted)
$state.go('publicState');
return permissions;
});
}
}
})
解决在转移到新状态之前等待承诺解决
更好:
function checkPermissions(requiredPermissions){
return function ($http, $state){ //Note: you can inject your own services/factories too
return $http.get(...).then(function(response){
var permissions = response.data.permissions;
var granted = permissions.reduce((prev,curr) => requiredPermissions.indexOf(curr) > -1 || prev, false);
if(!granted)
$state.go('publicState');
return permissions;
});
}
}
//In state definition
.state('root.some_page', {
url: '/',
templateUrl: 'some_page.html',
controller: 'home',
resolve: {
access: checkPermissions(['first','second'])
}
})
听起来不错,谢谢。但是如果我有许多受保护的路由,那就意味着我必须为我的所有状态复制所有这些代码?或者创建一个函数,该函数将权限列表作为参数,并返回一个针对这些权限进行验证的函数。我将编辑我的答案。