Javascript Angular ui-router:如何防止访问状态

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28518181/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:55:17  来源:igfitidea点击:

Angular ui-router: how to prevent access to a state

javascriptangularjsangular-ui-router

提问by spuleri

Hello I'm new to angularJS and have been trying to prevent access to certain states based on user critera.

您好,我是 angularJS 的新手,并且一直在尝试根据用户标准阻止对某些状态的访问。

This, from ui-router's FAQdescribes exactly what I want to do, but I cant get it to work properly. What do I need to but in the data object exactly to accomplish this?

这个,来自 ui-router's FAQ准确地描述了我想要做什么,但我无法让它正常工作。我需要什么,但在数据对象中完全可以做到这一点?

(I saw someone throwing in "true" on some blog post tutorial and using it like how I have, but that doesnt seem to work because I get an error that says needAdmin is not defined)

(我看到有人在一些博客文章教程中输入“true”并像我一样使用它,但这似乎不起作用,因为我收到一个错误,提示没有定义需要管理)

Here is my code:

这是我的代码:

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');
    }

  });
}]);

采纳答案by user2301179

If a state has no data, then to.datais undefined. Try this:

如果状态没有data,则to.data未定义。尝试这个:

if (to.data && to.data.needAdmin && auth.user.roles[0] !== 'admin') {

回答by user3591367

The best way I have found to do this uses resolve:

我发现这样做的最佳方法是使用解析:

    $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");
               }
           }]
        }
    });

This will trigger an error, preventing the user from accessing this state if they are not allowed.

这将触发错误,阻止用户在不允许的情况下访问此状态。

If you need to show an error, or send the user to a different state, handle the $stateChangeError event:

如果您需要显示错误,或将用户发送到不同的状态,请处理 $stateChangeError 事件:

$rootScope.$on('$stateChangeError', function(e, toState, toParams, fromState, fromParams, error){

    if(error === "Not Authorized"){
        $state.go("notAuthorizedPage");
    }

If you want to check for admin access on all states, you could use a decorator to add the resolve to all states. Something like this:

如果您想检查所有状态的管理员访问权限,您可以使用装饰器将解析添加到所有状态。像这样的东西:

$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;
});

I implemented something like this for my current application. If user is not logged in, we forward the user to a login form. If non-admin user attempts to hit any admin state, we forward to an error page.

我为我当前的应用程序实现了这样的东西。如果用户未登录,我们会将用户转发到登录表单。如果非管理员用户尝试进入任何管理员状态,我们会转发到错误页面。