Dans cet article vous apprendez ce que sont les guards dans le framework Angular et comment les utiliser.
Introduction
Dans une application traditionnelle où le backend génère la page à afficher,
on vérifierait côté serveur l'autorisation d'accès aux pages
et on renverrait une erreur 403
si l'utilisateur ne possède pas l'autorisation d'accès.
Dans une application utilisant un framework SPA comme Angular, toutes les pages sont détenues par l'utilisateur dès le premier chargement. Donc restreindre l'accès à certaines pages devient la responsabilité du front-end. Et pour gérer ces restrictions les développeurs du framework Angular ont créé : Les Router Guards.
Avec les Router Guards vous pouvez empêcher l'utilisateur d'accéder à certaines routes s'ils n'ont pas l'autorisation requise, ou de manière plus générale intercepter un changement de route pour y exécuter du code avant que la route ne se charge.
Type de guards
Voici la liste exhaustive des guards
d'Angular :
- CanActivate : Vérifie si un utilisateur peut accéder à une route
- CanActivateChild : Vérifie si un utilisateur peut accéder a une route enfant
- CanDeactivate : Vérifie si un utilisateur peut quitter une route
- Resolve : Récupère les données d'une route avant l'activation d'une route
- CanLoad : Vérifie si un utilisateur peut accéder à un module lazy-loading
Dans cet article, nous allons parler des 3 premiers types listés ci-dessus. Les resolvers et le guard CanLoad
feront l'objet d'un article dédié.
La CLI peut vous aider à générer un guard. Entrez cette commande à la racine de votre projet :
Puis sélectionnez le type de guard souhaité.
CanActivate
Les guards sont implémentés en tant que services et doivent être injectés. Ils disposent donc du décorateur @Injectable
.
Les guards retournent soit true
si la navigation et autorisée, soit false
dans le cas contraire.
Vous pouvez également renvoyer un Observable
ou une Promise
émettant un booléen, si par exemple vous devez contacter une API.
Voici le code du fichier que la CLI génère :
Dans cet exemple, la fonction canActivate
renvoie true dans tous les cas, donc le guard n'a aucun effet et laisse la navigation avoir lieu.
providedIn
ou la liste de providers de votre module.
Ensuite, ajoutez le guard à une ou plusieurs routes via la propriété canActivate :
La route /pokemon/{pokemonId}
ainsi que les routes enfant /pokemon/{pokemonId}/attack
et /pokemon/{pokemonId}/bio
sont désormais restreintes pas le guard.
Pour l'instant le guard n'effectue aucune vérification et laisse donc l'utilisateur accéder à la route. Voyons le cas le plus typique pour le canActivate, comment refuser un utilisateur non-authentifié.
Admettons que vous avez un userService
qui implémente une fonction isLoggedIn()
qui vous renvoie true si l'utilisateur est connecté, false sinon.
Le guard autorisera l'accès à l'utilisateur s'il est connecté. Sinon la navigation sera annulée et vous resterez sur la page courante.
Router
dans votre guard pour rediriger l'utilisateur avant de renvoyer false
.
CanActivateChild
Le guard canActivateChild
, fonctionne de la même manière sauf qu'il restreint uniquement l'accès aux routes enfant.
La route /pokemon/{pokemonId}
n'est pas gérée par le guard, mais les routes enfant /pokemon/{pokemonId}/attack
et /pokemon/{pokemonId}/bio
sont désormais restreintes pas le guard.
CanDeactivate
Le guard CanDeactivate
dans Angular, permet de réagir quand on quitte une route, généralement pour demander une action à l'utilisateur avant qu'il ne quitte la page
Prenons l'exemple d'une demande de confirmation à l'utilisateur pour quitter la page
Dans le composant de la page que vous allez quitter, créez une méthode canExit
. Dans la méthode canExit, vous pouvez vérifier s'il y a des données non sauvegardées, etc.
Si oui, demandez la confirmation si l'utilisateur veut quitter la page ou non. Renvoyez true
pour quitter le composant sinon retourne false
pour rester dans le même composant.
Ensuite, créez un service de garde, qui implémente l'interface CanDeactivate.
Pour finir mettez à jour votre route :
Les paramètres
Vous pouvez voir aussi des paramètres à la fonction du guard implémenter par Angular :
- route: ActivatedRouteSnapshot
- state: RouterStateSnapshot
Le paramètre route représente la route où sera dirigé l'utilisateur si le guard renvoi true. Vous pouvez l'utiliser pour extraire les paramètres de cette route pour la logique de votre guard.
Le paramètre state est l'objet qui contient toutes les variables du routeur dans l'état actuel. Idem vous pouvez l'utiliser pour extraires ces variables pour la logique de votre guard.
Conclusion
Voilà l'article touche à sa fin, vous avez vu les concepts de base des guards en espérant que cela vous sera utile.
N'hésitez pas à laisser un commentaire !