C'est quoi un Guard ?
Un Guard permet dâautoriser ou non la navigation vers une route. Il existe plusieurs types de Guard
dans Angular.
CanActivate
Un cas courant est une route quâon ne peut accĂ©der que si on est connectĂ© Ă lâapplication.
export function isLoggedInGuard(): CanActivateFn {
return (route, state) => {
const router = inject(Router);
const isAuthenticated = inject(AuthService).isAuthenticated;
if (isAuthenticated()) return true;
return this.router.parseUrl("/login");
};
}
Ici on a définit un Guard
qui vĂ©rifie si le user est connectĂ©, si câest le cas on renvoie true
donc on peut accéder à la route, sinon on retourne la route login
ce qui annule la navigation précédente et navigue vers la route login
.
Il ne nous reste plus quâĂ utiliser ce Guard
dans une Route
.
export const routes: Route[] = [
{
path: "profile",
component: ProfileComponent,
canActivate: [isLoggedInGuard],
},
];
CanDeactivate
canDeactivate
est lâinverse de canActivate
. Il permet de vérifier si on peut quitter une route. Par exemple, si on a un formulaire non sauvegardé, on pourrait vouloir afficher un message de confirmation avant de quitter la route.
export const canDeactivateFeedbackRouteGuard: CanDeactivateFn<FeedbackRoute> = (
component: FeedbackRoute
) => {
if (!component.formCompleted()) {
return window.confirm("Are you sure you want to leave?");
} else {
return true;
}
};
Ici, on vĂ©rifie si le formulaire est complĂ©tĂ©, si ce nâest pas le cas on demande une confirmation avant de quitter la route.
On utilise ce Guard
de la mĂȘme maniĂšre que canActivate
en le plaçant dans la route.
CanMatch
canMatch
permet de vĂ©rifier si une route peut ĂȘtre activĂ©e, tout comme canActivate
, mais si ce nâest pas le cas alors le router va essayer de matcher une autre route avec le mĂȘme path.
export function hasRoleGuard(role: Role): CanActivateFn {
return (route, state) => {
const role$ = inject(UserStore).role$:
// actuellement ce role đ est 'student'
return role$.pipe(map(userRole => userRole === role));
};
}
export const appRoutes: Route[] = [
{
path: "room",
loadComponent: () => import("./teachers-room.component"),
// grĂące Ă canMatch, le router va sauter ce path et essayer
// le path 'room' suivant car đ renvoie false
canMatch: [hasRoleGuard("teacher")],
},
{
path: "room",
loadComponent: () => import("./students-room.component"),
// et ici, đ renvoie true donc đ va ĂȘtre chargĂ©
canMatch: [hasRoleGuard("student")],
},
];