Aller au contenu principal

38-2 Guards et autorisation

La dernière étape est de protéger des actions (routes) de contrôleur afin de vérifier que la requête provient d'un utilisateur valide.

Préparation

Il faut vous assurer que vous ayez un jeton JWT valide pour la suite, puisqu'on enverra des requêtes contenant ce jeton.

  1. Premièrement, assurez-vous d'obtenir le jeton d'un utilisateur valide via une requête de connexion. Par exemple: Imgur

  2. Ensuite, utilisez le jeton reçu pour faire une requête quelconque au serveur (liste de projets par exemple). Mettez votre jeton dans la section Auth de la requête, sous Bearer Token Imgur

  3. Faites votre requête

info

Je fais une requête pour obtenir la liste de projets

Rien de différent cependant! La requête s'effectue et pas de trace particulière dans la console.

info

Pour que le mécanisme d'autorisation soit pris en considération, il faut le préciser dans la ou les actions de contrôleur. En effet, ce n'est pas nécessairement tous les contrôleurs et leurs actions qui requièrent de l'authentification/autorisation. Par exemple, pour créer un compte, on n'est évidemment pas connecté!

Protection d'actions via un guard (@UseGuards)

Pour protéger une route (action findAll du contrôleur de projets dans mon cas), on peut utiliser le décorateur @UseGuards(AuthGuard('jwt')).

src/projets/projets.controller.ts
@ApiOkResponse({
type: [Projet],
})
@Get()
@UseGuards(AuthGuard('jwt'))
async findAll() {
return this.projetsService.obtenirTous();
}
info

@UseGuards indique que l'action doit être protégée par un ou plusieurs guards. Par exemple, on pourrait aussi avoir un guard de rôle (utilisateur ou administrateur) AuthGuard('jwt') est un guard d'authentification lié à la stratégie d'authentification JWT du module Auth. En précisant jwt, c'est notre guard qui sera pris en considération.

Test de requête avec et sans jeton

Vous pouvez réessayer la même requête qu'au début, mais de deux façons différentes:

  • Sans jeton dans l'en-tête
  • Avec jeton

Avec jeton, la requête devrait fonctionner normalement puisqu'elle authentifiera votre utilisateur. D'ailleurs, vous devriez voir dans la console quelque chose comme ceci lors de l'exécution de la requête:

SELECT "Utilisateur"."id" AS "Utilisateur_id", "Utilisateur"."prenom" AS "Utilisateur_prenom", "Utilisateur"."nom" AS "Utilisateur_nom", "Utilisateur"."courriel" AS "Utilisateur_courriel", "Utilisateur"."nomUtilisateur" AS "Utilisateur_nomUtilisateur", "Utilisateur"."password" AS "Utilisateur_password", "Utilisateur"."date_creation" AS "Utilisateur_date_creation", "Utilisateur"."date_modification" AS "Utilisateur_date_modification" FROM "utilisateurs" "Utilisateur" WHERE ("Utilisateur"."courriel" = $1) LIMIT 1 -- PARAMETERS: ["benoit.tremblay@cegepdrummond.ca"]

Au fond, la fonction validate de la stratégie d'authentification récupère l'utilisateur de la base de données pour vérifier qu'il existe et peut accéder à l'application.

Cependant, sans jeton, vous obtiendrez:

{
"message": "Unauthorized",
"statusCode": 401
}

Protection d'un contrôleur en entier plutôt qu'une seule action

Bien qu'il est possible de protéger chaque route individuellement, lorsque le contrôleur en entier a besoin d'être protégé, le guard peut être ajouté directement au niveau de la classe du contrôleur. Cela vous évite d'avoir à réécrire @UseGuards... pour chaque action, et surtout, évite les oublis lorsqu'on ajoute une nouvelle action.

src/projets/projets.controller.ts
@ApiTags('projets')
@Controller('projets')
@UseGuards(AuthGuard('jwt'))
export class ProjetsController {

Level Up