Angular UI路由器:如何防止访问状态
你好,我是angularJS的新手,并试图阻止访问基于用户标识的某些状态。
这从ui路由器的FAQ描述了我想要做什么,但是我不能让它正常工作。 我需要什么,但在数据对象完全是为了完成这个?
(我看到有人在一些博客文章中引用了“真实”,并像我一样使用它,但似乎没有工作,因为我得到一个错误,说明needAdmin没有定义)
这是我的代码:
angular.module('courses').config(['$stateProvider', function($stateProvider) { // Courses state routing $stateProvider. state('listCourses', { url: '/courses', templateUrl: 'modules/courses/views/list-courses.client.view.html' }). state('createCourse', { url: '/courses/create', templateUrl: 'modules/courses/views/create-course.client.view.html', data: { needAdmin: true } }). state('viewCourse', { url: '/courses/:courseId', templateUrl: 'modules/courses/views/view-course.client.view.html' }). state('editCourse', { url: '/courses/:courseId/edit', templateUrl: 'modules/courses/views/edit-course.client.view.html', data: { needAdmin: true } }); } ]); angular.module('courses').run(['$rootScope', '$state', 'Authentication', function($rootScope, $state, Authentication) { $rootScope.$on('$stateChangeStart', function(e, to) { var auth = Authentication; console.log(auth.user.roles[0]); if (to.data.needAdmin && auth.user.roles[0] !== 'admin') { e.preventDefault(); $state.go('/courses'); } }); }]);
如果一个状态没有data
,那么to.data
是未定义的。 尝试这个:
if (to.data && to.data.needAdmin && auth.user.roles[0] !== 'admin') {
我发现要做到这一点的最佳方式是使用解决方法:
$stateProvider. state('createCourse', { url: '/courses/create', templateUrl: 'modules/courses/views/create-course.client.view.html', resolve: { security: ['$q', function($q){ if(/*user is not admin*/){ return $q.reject("Not Authorized"); } }] } });
这将触发一个错误,防止用户访问这个状态,如果他们不被允许的话。
如果您需要显示错误或将用户发送到其他状态,请处理$ stateChangeError事件:
$rootScope.$on('$stateChangeError', function(e, toState, toParams, fromState, fromParams, error){ if(error === "Not Authorized"){ $state.go("notAuthorizedPage"); }
如果你想检查所有状态的pipe理员访问,你可以使用一个装饰器来添加parsing到所有的状态。 像这样的东西:
$stateProvider.decorator('data', function(state, parent){ var stateData = parent(state); var data = stateData.data || {}; state.resolve = state.resolve || {}; if(data.needAdmin){ state.resolve.security = ['$q', function($q){ if(/*user is not admin*/){ return $q.reject("Not Authorized"); } }]; return stateData; });
我为我目前的应用程序实现了这样的东西。 如果用户没有login,我们将用户转到login表单。 如果非pipe理员用户尝试点击任何pipe理员状态,我们转发到错误页面。