Fermer

mars 13, 2024

Implémentation du contrôle d’accès basé sur les rôles dans NestJS

Implémentation du contrôle d’accès basé sur les rôles dans NestJS


NestJS est un framework Node.js progressif permettant de créer des applications côté serveur efficaces, fiables et évolutives. Une condition préalable à cet article est une compréhension de base de NestJS. Si vous avez travaillé sur des applications Web Node.js et souhaitez implémenter des applications utilisant une programmation basée sur les objets, telle que Java, NestJS est la solution idéale. La courbe d’apprentissage n’est pas non plus très longue si vous êtes familier avec Node.js. Dans cet article, nous apprendrons et mettrons en œuvre un contrôle d’accès basé sur les rôles et comment gérer les rôles et les autorisations dans les applications NestJS. Par souci de simplicité, nous ne considérerons pour l’instant que trois rôles statiques simples et non des rôles dynamiques.

Présentation du contrôle d’accès basé sur les rôles

Le contrôle d’accès est un élément essentiel de la sécurité qui détermine qui est autorisé à accéder à certaines données, applications et ressources, et dans quelles circonstances. Cela signifie essentiellement que tous les utilisateurs ne seront pas autorisés à accéder, voir ou manipuler toutes les parties/modules des applications. Les utilisateurs recevront l’autorisation d’un super-administrateur ou d’une autorité supérieure pour accéder à n’importe quel module système. Voyons maintenant comment fonctionne le contrôle d’accès dans NestJS dans les étapes suivantes :

-> Nous ne considérons que trois rôles dans le cadre de cet article, à savoir Super-Admin, Admin et Viewer.

-> Tout d’abord, nous allons commencer par créer un fichier role.enum.ts. Un Enum (abréviation de énumération) est un type de données spécial dans de nombreux langages de programmation représentant un ensemble distinct de valeurs nommées. Il est utilisé pour créer des types de données personnalisés avec une collection de noms et leurs valeurs correspondantes, rendant le code plus lisible et moins sujet aux erreurs. Nous allons créer un fichier enums pour stocker les rôles que nous utiliserons dans l’application. Voici l’extrait de code :

export enum Role { SUPER_ADMIN = 'SUPER_ADMIN', ADMIN = 'ADMIN', VIEWER = 'VIEWER' }

-> Ensuite, nous allons créer le fichier rôles.decorator.ts. Un décorateur est un objet appelable utilisé pour modifier (décorer) un autre objet appelable, tel que des fonctions ou des classes. Par exemple, une fonction qui ajoute une nouvelle fonctionnalité à une autre fonction sans changer son code est un décorateur. Dans notre cas d’utilisation, nous allons créer un décorateur personnalisé appelé rôles, qui sera utilisé dans les routes API pour transmettre les rôles spécifiques autorisés sur une route particulière. Si l’utilisateur ne dispose pas de ces rôles, il ne sera pas autorisé à accéder à cet itinéraire particulier. Regardons l’extrait de code sur la façon de créer des rôles de décorateur :

import { CustomDecorator, SetMetadata } from '@nestjs/common'; import { Role } from '../enums/role.enum'; export const Roles = (...roles: Role[]): CustomDecorator<string> => SetMetadata('roles', roles);

Ici, nous définissons les métadonnées avec la clé comme « rôles » et définissons la valeur comme un tableau de rôles à venir chaque fois que la fonction de décorateur est appelée sur une route avec différents rôles comme arguments. Nous y reviendrons plus tard dans l’article.

-> Ensuite, nous allons créer le fichier rôles.guard.ts. Les classes de garde agissent comme une première ligne de défense, garantissant que seules les données valides transitent. Ils sont comme des filtres qui capturent les débris avant qu’ils n’obstruent le système. Ainsi, dans notre cas, le rôle de garde agira comme une couche d’autorisation qui empêchera l’utilisateur d’accéder à n’importe quelle route s’il n’a pas le rôle concerné. Voyons comment écrire une garde dans l’extrait de code suivant :

import { CanActivate, ExecutionContext, Injectable } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { Role } from '../enums/role.enum'; @Injectable() export class RolesGuard implements CanActivate { constructor(private reflector: Reflector) {} canActivate(context: ExecutionContext): boolean { const requiredRoles = this.reflector.getAllAndOverride<Role[]>('roles', [ context.getHandler(), context.getClass(), ]); if (!requiredRoles) {  return true; } const { user } = context.switchToHttp().getRequest();  return requiredRoles.some((role) => user.role === role); } }

Ici, nous obtenons les rôles définis dans les métadonnées d’une route particulière et comparons ces rôles avec le rôle de l’utilisateur provenant de l’objet de requête. Si le rôle correspond, alors nous renvoyons vrai sinon faux. Si le garde renvoie false, l’itinéraire renverra une réponse non autorisée.

-> Enfin, nous devons appliquer les rôles implémentés sur notre route API. Reportez-vous à l’extrait de code suivant pour cela :

@Get('search') @Roles('viewer') @UseGuards(RolesGuard) async searchUser(@Query('queryString') queryString: string): Promise<void> {  return this.userService.searchUser(queryString); }

Ici, nous appliquons le rôle de spectateur sur un itinéraire particulier et implémentons la protection des rôles pour vérifier le rôle de l’utilisateur. De la même manière, nous pouvons également appliquer le reste des rôles.

Conclusion

De cette façon, nous pouvons implémenter un contrôle d’accès simple basé sur les rôles dans les applications NestJS. J’espère que vous l’avez compris et apprécié. Connectez-vous pour d’autres blogs techniques de ce type à l’avenir 😀

VOUS TROUVEZ CECI UTILE ? PARTAGEZ-LE






Source link