web-dev-qa-db-fra.com

Angular ui-router: comment empêcher l'accès à un état

Bonjour, je suis nouveau sur angularJS et j'ai essayé d'empêcher l'accès à certains états en fonction des critères de l'utilisateur.

Ceci, de la FAQ de ui-router décrit exactement ce que je veux faire, mais je ne peux pas le faire fonctionner correctement. De quoi ai-je besoin, mais dans l'objet de données exactement pour accomplir cela?

(J'ai vu quelqu'un lancer "vrai" sur un tutoriel de blog et l'utiliser comme je l'ai fait, mais cela ne semble pas fonctionner parce que je reçois une erreur qui dit que needAdmin n'est pas défini)

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

  });
}]);
40
spuleri

Si un état n'a pas de data, alors to.data n'est pas défini. Essaye ça:

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

La meilleure façon que j'ai trouvée pour faire cela utilise résoudre:

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

Cela déclenchera une erreur, empêchant l'utilisateur d'accéder à cet état s'il n'est pas autorisé.

Si vous devez afficher une erreur ou envoyer l'utilisateur dans un état différent, gérez l'événement $ stateChangeError:

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

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

Si vous souhaitez vérifier l'accès administrateur sur tous les états, vous pouvez utiliser un décorateur pour ajouter la résolution à tous les états. Quelque chose comme ça:

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

J'ai implémenté quelque chose comme ça pour mon application actuelle. Si l'utilisateur n'est pas connecté, nous le transmettons à un formulaire de connexion. Si un utilisateur non administrateur tente d'atteindre n'importe quel état administrateur, nous transmettons à une page d'erreur.

91
user3591367