Vous êtes sur la page 1sur 28

Angular : guard

Achref El Mouelhi

Docteur de l’université d’Aix-Marseille


Chercheur en programmation par contrainte (IA)
Ingénieur en génie logiciel

elmouelhi.achref@gmail.com

H & H: Research and Training 1 / 19


Plan

1 Introduction

2 Création

3 Exemple avec CanActivate

4 Exemple avec CanDeactivate

H & H: Research and Training 2 / 19


Introduction

Angular

Guard ?
Un service Angular (donc décoré par @Injectable) qui
implémente une des interfaces suivantes H I ©
UEL
CanDeactivate : vérifie L M O
CanActivate : vérifie si un utilisateur peut visiter une route.

f E si un utilisateur peut quitter une route.


re : vérifie si un utilisateur peut visiter les routes
c h
CanActivateChild
enfants.A
©
CanLoad : vérifie si un utilisateur peut aller sur une route d’un
module défini avec un lazy loading

H & H: Research and Training 3 / 19


Introduction

Angular

Exemple
H I ©
UEL
On veut que l’accès à la route /adresse soit seulement autorisé
O
aux utilisateurs authentifiés
f E LM
ch r e
On va créer une guard auth et l’associer à la route adresse
©A

H & H: Research and Training 4 / 19


Création

Angular

Pour créer une guard

H I ©
EL
ng generate guard guard-name

O U
f E LM
ch r e
©A

H & H: Research and Training 5 / 19


Création

Angular

Pour créer une guard

H I ©
EL
ng generate guard guard-name

O U
f E LM
Ou le raccourci ch r e
ng g g guard-name ©A

H & H: Research and Training 5 / 19


Création

Angular

Pour notre exemple, on va créer une garde qui vérifie si un


utilisateur est authentifié avant de charger certaines routes
ng g g guards/auth
H I ©
UEL
O
f E LM
ch r e
©A

H & H: Research and Training 6 / 19


Création

Angular

Pour notre exemple, on va créer une garde qui vérifie si un


utilisateur est authentifié avant de charger certaines routes
ng g g guards/auth
H I ©
UEL
O
f E LM
Dans le menu qui s’affiche
ch r e
©A
Pointer sur CanActivate
Puis cliquer une première fois sur espace et une deuxième sur
entrée

H & H: Research and Training 6 / 19


Création

Angular

On peut aussi préciser dans la commande l’interface à


implémenter
H I ©
ng g g guards/auth --implements CanActivate
UEL
O
f E LM
ch r e
©A

H & H: Research and Training 7 / 19


Création

Angular

On peut aussi préciser dans la commande l’interface à


implémenter
H I ©
ng g g guards/auth --implements CanActivate
UEL
O
f E LM
ch r e
©A
Résultat
CREATE src/app/guards/auth.guard.spec.ts (346 bytes)
CREATE src/app/guards/auth.guard.ts (456 bytes)

H & H: Research and Training 7 / 19


Exemple avec CanActivate

Contenu du auth.guard.ts
import { Injectable } from ’@angular/core’;
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot,
UrlTree } from ’@angular/router’;
import { Observable } from ’rxjs’;

@Injectable({
providedIn: ’root’
})
H I ©
EL
export class AuthGuard implements CanActivate {
canActivate(
next: ActivatedRouteSnapshot,
O U
f E LM
state: RouterStateSnapshot): Observable<boolean | UrlTree> |
Promise<boolean | UrlTree> | boolean | UrlTree {
return true;
ch r e
©A
}
}

H & H: Research and Training 8 / 19


Exemple avec CanActivate

Contenu du auth.guard.ts
import { Injectable } from ’@angular/core’;
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot,
UrlTree } from ’@angular/router’;
import { Observable } from ’rxjs’;

@Injectable({
providedIn: ’root’
})
H I ©
EL
export class AuthGuard implements CanActivate {
canActivate(
next: ActivatedRouteSnapshot,
O U
f E LM
state: RouterStateSnapshot): Observable<boolean | UrlTree> |
Promise<boolean | UrlTree> | boolean | UrlTree {
return true;
ch r e
©A
}
}

ActivatedRouteSnapshot : contient des informations comme les paramètres envoyés


pour la route demandée...

RouterStateSnapshot :contient des informations comme l’URL de la route demandée

La méthode canActivate ne fait aucun contrôle car elle retourne toujours true

H & H: Research and Training 8 / 19


Exemple avec CanActivate

Angular
Associons AuthGuard à la route /adresse dans
app-routing.module.ts
const routes: Routes = [
// les autres routes
{
H I ©
path: ’adresse’,
UEL
O
LM
component: AdresseComponent,
canActivate: [AuthGuard]
r e f E
ch
},

©A
{ path: ’auth’, component: AuthComponent },
// le reste des routes
];

H & H: Research and Training 9 / 19


Exemple avec CanActivate

Angular
Associons AuthGuard à la route /adresse dans
app-routing.module.ts
const routes: Routes = [
// les autres routes
{
H I ©
path: ’adresse’,
UEL
O
LM
component: AdresseComponent,
canActivate: [AuthGuard]
r e f E
ch
},

©A
{ path: ’auth’, component: AuthComponent },
// le reste des routes
];

La route /auth va permettre d’exécuter le composant


AuthComponent et afficher et gérer l’authentification
H & H: Research and Training 9 / 19
Exemple avec CanActivate

Angular

Contenu de auth.component.html
<h1>Page d’authentification</h1>
<form (ngSubmit)="isAuthenticated()">
<div>
H I ©
EL
Nom d’utilisateur :
<input type=text [(ngModel)]=login name=login>
O U
LM
</div>
<div>
r e f E
ch
Mot de passe :

©A
<input type=text [(ngModel)]=password name=password>
<button type=submit>Se connecter</button>
</div>
<div [hidden]=’erreur’>Identifiants incorrects</div>
</form>

H & H: Research and Training 10 / 19


Exemple avec CanActivate

Contenu de auth.component.ts
import { Component, OnInit } from ’@angular/core’;
import { Router } from ’@angular/router’;

@Component({
selector: ’app-auth’,
templateUrl: ’./auth.component.html’,
styleUrls: [’./auth.component.css’]
})
H I ©
EL
export class AuthComponent implements OnInit {
erreur = true;
password = ’’;
O U
login = ’’;

f E
constructor(private router: Router) { } LM
ngOnInit() { }
ch r e
©A
isAuthenticated() {
if (this.login === ’wick’ && this.password === ’john’) {
localStorage.setItem(’isConnected’, ’true’);
this.router.navigateByUrl(’/personne’);
} else {
this.erreur = false;
}
}
}
H & H: Research and Training 11 / 19
Exemple avec CanActivate

Mettons à jour le contenu de auth.guard.ts

import { Injectable } from ’@angular/core’;


import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot,
Router } from ’@angular/router’;

@Injectable({
providedIn: ’root’
})
export class AuthGuard implements CanActivate {
H I ©
U EL
MO
constructor(private router: Router) { }

canActivate(
f E L
r
next: ActivatedRouteSnapshot,

ch e
state: RouterStateSnapshot): boolean {

return true;
} else {
©A
if (Boolean(localStorage.getItem(’isConnected’))) {

this.router.navigateByUrl(’/auth’);
return false;
}
}
}

H & H: Research and Training 12 / 19


Exemple avec CanActivate

Angular

Pour tester H I ©
UEL
O
Essayez d’accéder à la route /adresse sans authentification

f E LM
ch r e
Authentifiez-vous avec les identifiants wick et john et réessayez

©A

H & H: Research and Training 13 / 19


Exemple avec CanDeactivate

Angular
Remarque

Préciser l’interface à implémenter pendant la génération existe depuis Angular 8

Angular-cli ne propose pas l’interface CanDeactivate

On va spécifier l’interface CanActivate puis on modifie


H I ©
U EL
O
f E LM
ch r e
©A

H & H: Research and Training 14 / 19


Exemple avec CanDeactivate

Angular
Remarque

Préciser l’interface à implémenter pendant la génération existe depuis Angular 8

Angular-cli ne propose pas l’interface CanDeactivate

On va spécifier l’interface CanActivate puis on modifie


H I ©
U EL
O
f E LM
Exécutons la commande suivante

ch r e
©A
ng g g guards/leave

H & H: Research and Training 14 / 19


Exemple avec CanDeactivate

Angular
Remarque

Préciser l’interface à implémenter pendant la génération existe depuis Angular 8

Angular-cli ne propose pas l’interface CanDeactivate

On va spécifier l’interface CanActivate puis on modifie


H I ©
U EL
O
f E LM
Exécutons la commande suivante

ch r e
©A
ng g g guards/leave

Le résultat
CREATE src/app/guards/leave.guard.spec.ts (352 bytes) CREATE
src/app/guards/leave.guard.ts (472 bytes)

H & H: Research and Training 14 / 19


Exemple avec CanDeactivate

Code généré
@Injectable({
providedIn: ’root’
})
export class LeaveGuard implements CanActivate {
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree>
H I ©
| Promise<boolean | UrlTree> | boolean | UrlTree {
UEL
return true;
O
}
}

f E LM
ch r e
©A

H & H: Research and Training 15 / 19


Exemple avec CanDeactivate

Code généré
@Injectable({
providedIn: ’root’
})
export class LeaveGuard implements CanActivate {
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean | UrlTree>
H I ©
| Promise<boolean | UrlTree> | boolean | UrlTree {
UEL
return true;
O
}
}

f E LM
ch r e
Ensuite
© A
Remplacez CanActivate par CanDeactivate<FormulaireComponent>

Faites l’import pour CanDeactivate

Supprimer la méthode générée pour CanActivate et ajouter la méthode de


l’interface qu’il faut implémenter

H & H: Research and Training 15 / 19


Exemple avec CanDeactivate

Nouveau code
@Injectable({
providedIn: ’root’
})
export class LeaveGuard implements CanDeactivate<FormulaireComponent> {
canDeactivate(component: FormulaireComponent,
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot,
nextState?: RouterStateSnapshot): boolean {
H I ©
EL
throw new Error("Method not implemented.");

}
}
O U
f E LM
ch r e
©A

H & H: Research and Training 16 / 19


Exemple avec CanDeactivate

Nouveau code
@Injectable({
providedIn: ’root’
})
export class LeaveGuard implements CanDeactivate<FormulaireComponent> {
canDeactivate(component: FormulaireComponent,
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot,
nextState?: RouterStateSnapshot): boolean {
H I ©
EL
throw new Error("Method not implemented.");

}
}
O U
f E LM
Objectif
ch r e
©A
On ajoute le lien suivant dans formulaire.component.html :

<a routerLink=’/personne’>aller ailleurs</a>

Si l’utilisateur remplit les deux champs nom et prenom dans


formulaire.component.html et clique sur le lien pour aller sur le composant
personne, on lui demande une confirmation.

H & H: Research and Training 16 / 19


Exemple avec CanDeactivate

Angular

Modifions la garde

@Injectable({
providedIn: ’root’
})
H I ©
EL
export class LeaveGuard implements CanDeactivate<FormulaireComponent> {
canDeactivate(component: FormulaireComponent,
currentRoute: ActivatedRouteSnapshot,
O U
currentState: RouterStateSnapshot,

f E LM
nextState?: RouterStateSnapshot): boolean {

r e
return component.personne.nom === undefined ||
ch
©A
component.personne.prenom === undefined ||
component.personne.nom.length === 0 ||
component.personne.prenom.length === 0 ||
confirm(’voulez-vous vraiement quitter ?’);
}
}

H & H: Research and Training 17 / 19


Exemple avec CanDeactivate

Angular
Associons LeaveGuard à la route /formulaire dans
app-routing.module.ts
const routes: Routes = [
// les autres routes
{
path: ’adresse’,
H I ©
component: AdresseComponent,
UEL
O
LM
canActivate: [AuthGuard]
},
{
r e f E
ch
©A
path: ’formulaire’,
component: FormulaireComponent,
canDeactivate: [LeaveGuard]
},
{ path: ’auth’, component: AuthComponent },
// le reste des routes
];

H & H: Research and Training 18 / 19


Exemple avec CanDeactivate

Angular
Il est possible d’associer plusieurs guards à une route
const routes: Routes = [
// les autres routes
{
path: ’adresse’,
component: AdresseComponent,
H I ©
canActivate: [AuthGuard]
UEL
O
LM
},
{
path: ’formulaire’,
r e f E
ch
©A
component: FormulaireComponent,
canActivate: [AuthGuard],
canDeactivate: [LeaveGuard],
},
{ path: ’auth’, component: AuthComponent },
// le reste des routes
];

H & H: Research and Training 19 / 19

Vous aimerez peut-être aussi