Utilisation avec le routeur final
Avec l'introduction du nouveau routeur, il est devenu plus facile de garder les routes. Vous devez définir une garde, qui agit comme un service, et l'ajouter à l'itinéraire.
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();
}
}
Passez maintenant le LoggedInGuard
à la route et ajoutez-le également au providers
tableau du module.
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 },
];
La déclaration du module:
@NgModule({
declarations: [AppComponent, HomeComponent, LoginComponent]
imports: [HttpModule, BrowserModule, RouterModule.forRoot(routes)],
providers: [UserService, LoggedInGuard],
bootstrap: [AppComponent]
})
class AppModule {}
Article de blog détaillé sur son fonctionnement avec la version finale: https://medium.com/@blacksonic86/angular-2-authentication-revisited-611bf7373bf9
Utilisation avec le routeur obsolète
Une solution plus robuste consiste à étendre RouterOutlet
et lors de l'activation d'une route, vérifiez si l'utilisateur est connecté. De cette façon, vous n'avez pas à copier et coller votre directive dans chaque composant. De plus, la redirection basée sur un sous-composant peut être trompeuse.
@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()
}
}
Le UserService
représente l'endroit où réside votre logique métier, que l'utilisateur soit connecté ou non. Vous pouvez l'ajouter facilement avec DI dans le constructeur.
Lorsque l'utilisateur accède à une nouvelle URL sur votre site Web, la méthode d'activation est appelée avec l'instruction actuelle. À partir de là, vous pouvez saisir l'url et décider si elle est autorisée ou non. Sinon, redirigez-vous simplement vers la page de connexion.
Une dernière chose reste à faire pour que cela fonctionne, c'est de le passer à notre composant principal au lieu de celui intégré.
@Component({
selector: 'app',
directives: [LoggedInRouterOutlet],
template: template
})
@RouteConfig(...)
export class AppComponent { }
Cette solution ne peut pas être utilisée avec le @CanActive
décorateur de cycle de vie, car si la fonction qui lui est transmise résout false, la méthode activate duRouterOutlet
ne sera pas appelée.
A également écrit un article de blog détaillé à ce sujet: https://medium.com/@blacksonic86/authentication-in-angular-2-958052c64492