AngularJS | Gérer le routage avant qu'ils ne chargent

Je souhaite créer une vérification d'authentification simple pour mes itinéraires par service externe.

Je définis les exigences d'accès sur l'objet de route:

$routeProvider .when('/', { templateUrl: 'src/app/views/index.html', controller: 'indexCtrl', authenticated: true }) .when('/login', { templateUrl: 'src/app/views/login.html', controller: 'loginCtrl', anonymous: true }) .otherwise({ redirectTo: '/' }) ; 

Ensuite, je vérifie si j'ai l'autorisation dans l'événement $routeChangeStart .

 $rootScope.$on('$routeChangeStart', function (event, next) { if(next.authenticated && !$myService.isLoggedin()) $location.path("/login"); else if(next.anonymous && $myService.isLoggedin()) $location.path("/secured"); }); 

En fait, ça marche,
Si l'utilisateur n'est pas authentifié, il le déplace vers la page de connexion, s'il est authentifié, mais l'itinéraire est destiné aux utilisateurs anonymes, il les transmet à une autre page, etc.

MAIS – cette redirection se produit réellement après que les contrôleurs et les modèles sont chargés! Et cela fait que mon contrôleur effectue une demande inutile sur mon API REST, même si je ne suis pas authentifié.

Comment puis-je gérer l'itinéraire avant de procéder?

Utilisez $ routeProvider résoudre

 .when('/', { templateUrl: 'src/app/views/index.html', controller: 'indexCtrl', resolve: function($q, $location) { var deferred = $q.defer(); deferred.resolve(); if (!isAuthenticated) { $location.path('/login'); } return deferred.promise; } }) 

Ma solution combinait $locationChangeStart et $routeChangeStart :

 $rootScope.$on('$locationChangeStart', function (event) { //If login data not available, make sure we request for it if($facebook.isConnected()==null) { $facebook.getLoginStatus(); event.preventDefault(); return; } var next=parseRoute().$$route; if(!Auth.loginCheck(next)) event.preventDefault(); }); 

J'ai copié parseRoute() de angular-route.js pour analyser l'URL donnée à l'itinéraire ..

Ensuite, je Auth.loginCheck mon gestionnaire de vérification de connexion ( Auth.loginCheck ) de manière à ce que s'il échoue, il renvoie faux.

J'utilise également $routeChangeStart pour gérer les $route.reload() , alors maintenant, après chaque changement dans mon état d'authentification, je fais simplement $route.reload() :

 $rootScope.$on('$routeChangeStart', function (event, next) { Auth.loginCheck(next); }); 

Enfin, je m'assure simplement que ce service personnalisé fonctionnera toujours en utilisant la méthode run() simple.

Modifier:

Nous utilisons maintenant ngAuth, un module que nous avons conçu pour résoudre ce problème exact (basé sur la réponse que j'ai donnée ici avant).

Enfin, nous avons développé un module angulaire qui a résolu ce problème … Ce module est basé sur la réponse que j'ai publiée ici auparavant.

En raison des demandes ici, nous avons publié une version bêta qui fonctionne maintenant: http://github.com/GoDisco/ngAuth

N'hésitez pas à l'utiliser.

Angularjs résume l'exemple:

 .when('/profile', { templateUrl: 'views/profile.html', controller: 'ProfileCtrl', resolve: { app: function($q, $rootScope, $location) { var defer = $q.defer(); if ($rootScope.currentUser == undefined) { $location.path('/login'); }; defer.resolve(); return defer.promise; } } 

Angular-http-auth vous permet de gérer une autorisation très élégante au niveau HTTP (lors de la récupération du modèle) et vous invite à vous connecter si nécessaire. Tout cela sans même charger le modèle (ni le contrôleur) si l'autorisation est refusée. De toute évidence, la meilleure chose que j'ai vue jusqu'ici.

https://github.com/witoldsz/angular-http-auth

Essayez d'utiliser la propriété de resolve de l'itinéraire. Il résout toutes les fonctions / dépendances qui lui sont transmises avant que n'importe quel contrôleur ou modèle ne soit chargé. Incase la dépendance renvoie une promesse, jusqu'à ce que sa résolution ne soit pas chargée.

Essayez de passer votre service d'authentification dans la résolution et la redirection en cas d'échec d'authentification.

Regardez -> https://groups.google.com/forum/#!topic/angular/QtO8QoxSjYw

$ StateProvider utilise $ routeProvider en dessous. Ce wiki vous donnera plus de points de vue. https://github.com/angular-ui/ui-router/wiki#resolve