Je souhaite créer un contrôle d'authentification simple pour mes itinéraires par service externe.
Je définis les conditions d'accès sur l'objet 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 le $routeChangeStart
un événement.
$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, cela fonctionne-
si l'utilisateur n'est pas authentifié il le déplace vers la page de connexion, s'il est authentifié mais la route est pour les utilisateurs anonymes seulement il les déplace vers une autre page, etc.
MAIS- cette redirection se produit réellement après le chargement des contrôleurs et des modèles! Et cela fait que mon contrôleur fait une requête inutile à mon REST API, même si je ' ne suis pas authentifié.
Comment gérer l'itinéraire avant de le traiter?
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 à router ..
Ensuite, je crée mon gestionnaire de vérification de connexion (Auth.loginCheck
) De manière à ce que s'il échoue, il retourne faux.
J'utilise également $routeChangeStart
Pour gérer les événements $route.reload()
, donc maintenant, après chaque modification de 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é sera toujours exécuté en utilisant la méthode simple run()
.
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 auparavant).
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
Sentez-vous libre de l'utiliser.
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;
}
})
Essayez d'utiliser la propriété resolve
de la route. Il résout toutes les fonctions/dépendances qui lui sont transmises avant le chargement d'un contrôleur ou d'un modèle. Dans le cas où la dépendance renvoie une promesse, jusqu'à ce que sa résolution ne soit pas chargée.
Essayez de transmettre votre service d'authentification en résolution et redirigez en cas d'échec de l'authentification.
Veuillez jeter un œil -> https://groups.google.com/forum/#!topic/angular/QtO8QoxSjYw
$ stateProvider utilise $ routeProvider en dessous. Ce wiki vous donnera plus d'informations. https://github.com/angular-ui/ui-router/wiki#resolve
Exemple de résolution Angularjs:
.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 très élégamment les autorisations au niveau HTTP (lors de la récupération du modèle) et invite à la connexion si nécessaire. Tout cela sans même charger de modèle (ni contrôleur) si l'autorisation est refusée. De toute évidence, la meilleure chose que j'ai vue jusqu'à présent.