Verwendung mit dem endgültigen Router
Mit der Einführung des neuen Routers wurde es einfacher, die Routen zu bewachen. Sie müssen eine Wache definieren, die als Dienst fungiert, und sie der Route hinzufügen.
import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';
import { UserService } from '../../auth';
@Injectable()
export class LoggedInGuard implements CanActivate {
constructor(user: UserService) {
this._user = user;
}
canActivate() {
return this._user.isLoggedIn();
}
}
Übergeben Sie nun das LoggedInGuard
an die Route und fügen Sie es auch dem providers
Array des Moduls hinzu.
import { LoginComponent } from './components/login.component';
import { HomeComponent } from './components/home.component';
import { LoggedInGuard } from './guards/loggedin.guard';
const routes = [
{ path: '', component: HomeComponent, canActivate: [LoggedInGuard] },
{ path: 'login', component: LoginComponent },
];
Die Moduldeklaration:
@NgModule({
declarations: [AppComponent, HomeComponent, LoginComponent]
imports: [HttpModule, BrowserModule, RouterModule.forRoot(routes)],
providers: [UserService, LoggedInGuard],
bootstrap: [AppComponent]
})
class AppModule {}
Ausführlicher Blog-Beitrag zur Funktionsweise der endgültigen Version: https://medium.com/@blacksonic86/angular-2-authentication-revisited-611bf7373bf9
Verwendung mit dem veralteten Router
Eine robustere Lösung besteht darin, die RouterOutlet
und beim Aktivieren einer Routenprüfung zu erweitern, ob der Benutzer angemeldet ist. Auf diese Weise müssen Sie Ihre Direktive nicht in jede Komponente kopieren und einfügen. Außerdem kann eine Umleitung basierend auf einer Unterkomponente irreführend sein.
@Directive({
selector: 'router-outlet'
})
export class LoggedInRouterOutlet extends RouterOutlet {
publicRoutes: Array;
private parentRouter: Router;
private userService: UserService;
constructor(
_elementRef: ElementRef, _loader: DynamicComponentLoader,
_parentRouter: Router, @Attribute('name') nameAttr: string,
userService: UserService
) {
super(_elementRef, _loader, _parentRouter, nameAttr);
this.parentRouter = _parentRouter;
this.userService = userService;
this.publicRoutes = [
'', 'login', 'signup'
];
}
activate(instruction: ComponentInstruction) {
if (this._canActivate(instruction.urlPath)) {
return super.activate(instruction);
}
this.parentRouter.navigate(['Login']);
}
_canActivate(url) {
return this.publicRoutes.indexOf(url) !== -1 || this.userService.isLoggedIn()
}
}
Das UserService
steht für den Ort, an dem sich Ihre Geschäftslogik befindet, unabhängig davon, ob der Benutzer angemeldet ist oder nicht. Sie können es einfach mit DI im Konstruktor hinzufügen.
Wenn der Benutzer zu einer neuen URL auf Ihrer Website navigiert, wird die Aktivierungsmethode mit der aktuellen Anweisung aufgerufen. Daraus können Sie die URL abrufen und entscheiden, ob sie zulässig ist oder nicht. Wenn nicht, leiten Sie einfach zur Anmeldeseite weiter.
Eine letzte Sache, die noch funktioniert, ist, sie an unsere Hauptkomponente anstatt an die eingebaute zu übergeben.
@Component({
selector: 'app',
directives: [LoggedInRouterOutlet],
template: template
})
@RouteConfig(...)
export class AppComponent { }
Diese Lösung kann nicht mit dem @CanActive
Lifecycle Decorator verwendet werden, da die Aktivierungsmethode von RouterOutlet
nicht aufgerufen wird , wenn die an sie übergebene Funktion false auflöst .
Schrieb auch einen ausführlichen Blog-Beitrag darüber: https://medium.com/@blacksonic86/authentication-in-angular-2-958052c64492