【问题标题】:Angular ui-router: how to prevent access to a stateAngular ui-router:如何防止访问状态
【发布时间】:2016-06-29 13:40:35
【问题描述】:

您好,我是 angularJS 新手,一直在尝试根据用户条件阻止访问某些状态。

This, from ui-router's FAQ 准确地描述了我想要做的事情,但我无法让它正常工作。我需要在数据对象中做什么才能做到这一点?

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

这是我的代码:

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

  });
}]);

【问题讨论】:

  • UI 不应该有指向页面的链接,对吧?
  • @cgatian 我不知道...你能详细点吗?

标签: javascript angularjs angular-ui-router


【解决方案1】:

我发现最好的方法是使用 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");
               }
           }]
        }
    });

这将触发错误,如果不允许用户访问此状态,则会阻止用户访问此状态。

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

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

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

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

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

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

【讨论】:

  • resolve: { security: ['$q', function($q){ if(/*user is not admin*/){ return $q.reject("Not Authorized"); } }] } - 我怎样才能得到$q
  • promises 库,用于解决或拒绝该承诺...更多详细信息:docs.angularjs.org/api/ng/service/$q
  • 该解决方案的主要问题是在配置文件或 $stateProvider 定义的任何文件中获取用户角色。当我刷新页面时,我还没有用户角色。
  • 在允许访问之前如何访问服务以检查该服务上是否存在对象?
  • @user3591367 你确定var data = stateData.data || {}; 吗?不应该是var data = stateData || {};?在我的测试中,parent(state)state 返回'data' 值。
【解决方案2】:

如果一个状态没有data,那么to.data 是未定义的。试试这个:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多