Подтвердить что ты не робот

Angular ui-router: как предотвратить доступ к состоянию

Здравствуйте, я новичок в angularJS и пытаюсь предотвратить доступ к определенным состояниям на основе критерия пользователя.

Это, из ui-router 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');
    }

  });
}]);
4b9b3361

Ответ 1

Если состояние не имеет data, то to.data - undefined. Попробуйте следующее:

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

Ответ 2

Лучший способ, который я нашел для этого, - решить проблему:

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

Я применил что-то вроде этого для моего текущего приложения. Если пользователь не вошел в систему, мы пересылаем пользователя в форму для входа. Если пользователь, не являющийся администратором, пытается ударить любое состояние администратора, мы переходим на страницу с ошибкой.