Wie kann man canActivate Guard auf allen Routen anwenden?

76

Ich habe einen aktiven Schutz von angle2, der behandelt, wenn der Benutzer nicht angemeldet ist, ihn auf die Anmeldeseite umzuleiten:

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

Ich muss es auf jeder Route implementieren wie:

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] }
];

Gibt es eine bessere Möglichkeit, die Option canActive zu implementieren, ohne sie jedem Pfad hinzuzufügen?

Was ich möchte, ist, es auf der Hauptroute hinzuzufügen, und es sollte für alle anderen Routen gelten. Ich habe viel gesucht, aber ich konnte keine nützliche Lösung finden

Vielen Dank

Nimatullah Razmjo
quelle

Antworten:

176

Sie können eine komponentenlose übergeordnete Route einführen und den Guard dort anwenden:

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 }
    ]}
];
Günter Zöchbauer
quelle
Freut mich zu hören :) Danke für das Feedback.
Günter Zöchbauer
11
@ GünterZöchbauer Ich habe immer deinen Rat gelesen. Vielen Dank!! Aber in meinem Fall funktioniert das nicht. CanActive funktioniert nicht beim Routing zwischen Kindern. Ich benutze canActivateChild. Es klappt.
Smiranin
Schön zu hören, dass Sie meine Antworten hilfreich finden :) und danke, dass Sie canActivateChild
Günter Zöchbauer
3
Ich bin mir nicht sicher. Sie könnten es canActivateChildstattdessen versuchen canActivate. Ich habe das selbst noch nicht benutzt.
Günter Zöchbauer
2
Ja, canActivateChildist ein besserer Ansatz für das gegebene Szenario, um alle untergeordneten Routen einzuschließen. Und die Eltern selbst können mit canActivateoder canLoadabhängig davon, wann es in die App geladen wird, geschützt werden . Außerdem gibt das Code-Snippet in Version 6.0 Konsolenfehler aus, da Angular eine Komponenten- oder untergeordnete Deklaration in der Routenkonfiguration erwartet.
ashish.gd
13

Sie können auch die Routenänderungen des Routers in der ngOnInit-Funktion Ihrer app.component abonnieren und von dort aus die Authentifizierung überprüfen, z

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

Ich bevorzuge diese Art der Durchführung von App-weiten Überprüfungen, wenn sich eine Route ändert.

Alan Smith
quelle
Wie komme ich state.urlmit diesem Ansatz?
c.sankhala
3

Ich denke, Sie sollten "Child Routing" implementieren, mit dem Sie einen Elternteil (mit dem Pfad "admin" zum Beispiel) und seine Kinder haben können.

Anschließend können Sie dem Elternteil eine Aktivierung zuweisen, die den Zugriff auf alle seine Kinder automatisch einschränkt. Wenn ich beispielsweise auf "admin / home" zugreifen möchte, muss ich "admin" durchlaufen, das von canActivate geschützt wird. Sie können sogar ein übergeordnetes Element mit einem leeren Pfad "" definieren, wenn Sie möchten

Simrugh
quelle