87 votes

Comment appliquer la garde canActivate sur toutes les routes ?

J'ai un garde actif angular2 qui gère si l'utilisateur n'est pas connecté, le redirige vers la page de connexion :

import { Injectable } from  "@angular/core";
import { CanActivate , ActivatedRouteSnapshot, RouterStateSnapshot, Router} from "@angular/router";
import {Observable} from "rxjs";
import {TokenService} from "./token.service";

@Injectable()
export class AuthenticationGuard implements CanActivate {

    constructor (
        private router : Router,
        private token : TokenService
    ) { }

    /**
     * Check if the user is logged in before calling http
     *
     * @param route
     * @param state
     * @returns {boolean}
     */
    canActivate (
        route : ActivatedRouteSnapshot,
        state : RouterStateSnapshot
    ): Observable<boolean> | Promise<boolean> | boolean {
        if(this.token.isLoggedIn()){
            return true;
        }
        this.router.navigate(['/login'],{ queryParams: { returnUrl: state.url }});
        return;
    }
}

Je dois l'implémenter sur chaque route comme :

const routes: Routes = [
    { path : '', component: UsersListComponent, canActivate:[AuthenticationGuard] },
    { path : 'add', component : AddComponent, canActivate:[AuthenticationGuard]},
    { path : ':id', component: UserShowComponent },
    { path : 'delete/:id', component : DeleteComponent, canActivate:[AuthenticationGuard] },
    { path : 'ban/:id', component : BanComponent, canActivate:[AuthenticationGuard] },
    { path : 'edit/:id', component : EditComponent, canActivate:[AuthenticationGuard] }
];

Existe-t-il un meilleur moyen de mettre en œuvre l'option canActive sans l'ajouter à chaque chemin ?

Ce que je veux, c'est l'ajouter sur la route principale, et cela devrait s'appliquer à toutes les autres routes. J'ai beaucoup cherché, mais je n'ai pas trouvé de solution utile.

Merci

198voto

Günter Zöchbauer Points 21340

Vous pouvez introduire une route parentale sans composant et y appliquer la garde :

const routes: Routes = [
    {path: '', canActivate:[AuthenticationGuard], children: [
      { path : '', component: UsersListComponent },
      { path : 'add', component : AddComponent},
      { path : ':id', component: UserShowComponent },
      { path : 'delete/:id', component : DeleteComponent },
      { path : 'ban/:id', component : BanComponent },
      { path : 'edit/:id', component : EditComponent }
    ]}
];

15voto

Alan Smith Points 395

Vous pouvez également vous abonner aux changements de route du routeur dans la fonction ngOnInit de votre app.component et vérifier l'authentification à partir de là, par exemple.

    this.router.events.subscribe(event => {
        if (event instanceof NavigationStart && !this.token.isLoggedIn()) {
            this.router.navigate(['/login'],{ queryParams: { returnUrl: state.url}}); 
        }
    });

Je préfère cette façon d'effectuer tout type de vérification à l'échelle de l'application lorsqu'un itinéraire change.

3voto

Simrugh Points 67

Je pense que vous devriez implémenter le "routage des enfants" qui vous permet d'avoir un parent (avec un chemin "admin" par exemple) et ses enfants.

Vous pouvez ensuite appliquer un canactivate au parent qui restreindra automatiquement l'accès à tous ses enfants. Par exemple, si je veux accéder à "admin/home", je devrai passer par "admin" qui est protégé par canActivate. Vous pouvez même définir un parent avec un chemin vide "" si vous le souhaitez.

-3voto

CountZero Points 789

Je suis tombé sur cet exemple en cherchant et j'ai été surpris par l'exemple donné dans l'exemple.

Vous devez vous assurer que la garde renvoie true si vous voulez afficher les routes enfant.

@Injectable()
export class AuthenticationGuard implements CanActivate {

    constructor(
        private router: Router,
        private authService: AuthService) { }

    canActivate(
        route: ActivatedRouteSnapshot,
        state: RouterStateSnapshot
    ): Observable<boolean> | Promise<boolean> | boolean {

        // Auth checking code here

        // Make sure you return true here if you want to show child routes
        return true;
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X