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.
-
Premièrement, assurez-vous d'obtenir le jeton d'un utilisateur valide via une requête de connexion. Par exemple:

-
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
Authde la requête, sousBearer Token
-
Faites votre requête
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.
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')).
@ApiOkResponse({
type: [Projet],
})
@Get()
@UseGuards(AuthGuard('jwt'))
async findAll() {
return this.projetsService.obtenirTous();
}
@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.
@ApiTags('projets')
@Controller('projets')
@UseGuards(AuthGuard('jwt'))
export class ProjetsController {
