Pour vérifier le fonctionnement de vos JWT, il faudra bien entendu faire les appels de vos routes en passant le bon header (c.f. Doc)
- Installez les librairies
jsonwebtoken
,express-jwt
etbcryptjs
- Modifier la route de création d'un utilisateur
- Au lieu d'encrypter le mot de passe en
md5
, l'encrypter enbcrypt
avec unsalt
de 12 (c.f. Doc) - Supprimez la dépendance npm
md5
qui n'est désormais plus utilisée
- Au lieu d'encrypter le mot de passe en
- Créez une route d'authentification:
/auth/login
(ça sera l'occasion de créer un fichierauth.route.js
dans le répertoirecontrollers
de façon similaire auuser.route.js
)- Le body de la request contiendra les champs:
firstName
,password
- Cette API
/auth/login
devra:- Allez chercher dans les utilisateurs, celui dont le firstName correspond à celui dans le body de la request
- En fonction de l'utilisateur récupéré, comparez le password qu'il avait en base (encrypté) avec celui qui est dans le body de la request
- Si les passwords ne matchent pas => Renvoyez une response 401 Unauthorized
- Si les password matchent, on créé et retourne un jwt (grâce à la lib
jsonwebtoken
)
- Le body de la request contiendra les champs:
- Enfin, grâce à la lib
express-jwt
, vous allez créer un middleware qui vérifiera le token jwt dans toutes les routes de votre web server, sauf la création d'un utilisateur et la route de login (c.f. Doc + Et pour la partie "authorisation des routes sauf les routes XXXX", recherchez dans la doc le terme "unless
")
- Pour la gestion des validations de nos API, installez la librairie
express-validator
- Rajoutez les règles de validation suivantes pour les routes de création d'un utilisateur et d'authentification:
-
POST /users/login
=> le body de la request doit vérifier la présence des champsfirstName
etpassword
-
POST /users
=> le body de la request doit vérifier la présence des champsfirstName
,lastName
, etpassword
. Et ce dernier, doit avoir une taille minimum de 5 caractères
-
- Pour éviter de stocker le mot de passe d'encryptage du JWT en dur dans le code (et donc qu'il se retrouve poussé malencontreusement sur Git), vous allez utiliser le mécanisme des variables d'environnement
- Installez la librairie
dotenv
- Recherchez à travers la doc comment vous en servir pour faire en sorte que le
secret
utilisé pour encrypter le JWT soit récupéré depuis une variable d'environnement que vous aurez défini (nommée par exemple:JWT_SECRET
) - Grâce à la lib
jsonwebtoken
, au moment où vous créez le token, faites en sorte qu'il expire au bout d'une heure - Ensuite, créez une nouvelle variable d'environnement qui contiendra cette information (appelée admettons
JWT_EXPIRES_IN
) et servez vous en donc ensuite dans votre code. Dans des conditions réelles cela pourrait servir à dire: "En environnement de développement, je veux que mon JWT ait une durée de vie de 5 minutes pour vérifier son bon fonctionnement", alors que "En production, je veux qu'il ait une durée de vie de 24h, pour faire en sorte que l'utilisateur doive se reconnecter toutes les 24h" - Avant de pousser vos dernières modifications, vous remarquerez peut être que le fichier contenant les variables d'environnement sera poussé sur votre repository Git. Et vous voulez éviter cela. Faites donc en sorte que ça ne soit pas le cas
- Si jamais, suite au TP d'hier, vous aviez poussé sur votre Git votre fichier physique de base de donnée, supprimez le sur votre repository (mais pas en local car vous continuerez de vous en servir). Pour trouver comment faire, vous pouvez chercher par exemple: "git remove remote file"
- La dernière partie de ce TP concerna les rôles: Vous allez restreindre certains accès de votre application en fonction du rôle de l'utilisateur
- Dans le model User, rajoutez une propriété
isAdmin
qui sera un booléen non nullable - Il faudra donc que l'API de création d'un utilisateur soit capable de recevoir dans son body cette nouvelle information pour l'insérer dans la table User en base de donnée
- Ensuite, lors de l'authentification (
/auth/login
), vous allez récupérer cette information pour la stocker dans la partiepayload
du JWT que vous créez. La payload du JWT devra être sous la forme:{ userId: string, firstName: string, permissions: string[] }
(string[]
veut dire: "tableau de strings"). En fonction de si l'utilisateur est admin ou non, vous aurez:permissions: ['admin']
oupermissions: []
- Cherchez dans la doc de la lib
express-jwt
un endroit où on parle de "permissions" - Installez la lib des "permissions" correspondante, et utilisez là pour restreindre aux "admin" les routes de:
- Recherche d'utilisateur par son
firstName
- Modification de l'utilisateur
- Suppression de l'utilisateur
- Recherche d'utilisateur par son
- Si jamais l'utilisateur n'est pas "admin" le serveur doit renvoyer une 403 "Forbidden", grâce au middleware de gestion des erreurs