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 LoggedInGuardan die Route und fügen Sie es auch dem providersArray 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 RouterOutletund 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 UserServicesteht 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 @CanActiveLifecycle Decorator verwendet werden, da die Aktivierungsmethode von RouterOutletnicht 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