‫Jonas : Continuons maintenant à écrire
‫notre fonction protect middleware.
‫Ainsi, dans la dernière leçon, nous avons lu
‫le jeton à partir de
‫l'en-tête d'autorisation, puis vérifié si le jeton existe réellement.
‫Alors juste ici.
‫Et ensuite, nous avons l'étape de vérification pour le jeton.
‫Et j'espère que vous vous souvenez
‫qu'à cette étape, nous vérifions si quelqu'un a manipulé
‫les données ou aussi si le token a déjà expiré.
‫Nous avons donc déjà utilisé, à partir du package de jetons Web JSON, la
‫fonction assign function,
‫et maintenant nous allons utiliser la fonction verify.
‫Alors comme avant, jwt. vérifier, puis là-dedans,
‫comme vous pouvez l'imaginer, nous passons le jeton pour que l'algorithme
‫puisse lire la charge utile, puis se
‫rappeler que cette étape a également besoin du secret.
‫Donc en gros, afin de créer la signature de test.
‫Ce secret est donc un processus. env. JWT_SECRET.
‫Vous vous en souvenez ?
‫Maintenant, comme troisième
‫argument, cette fonction nécessite en fait une fonction de rappel.
‫Ce rappel sera donc
‫exécuté dès que la vérification sera terminée.
‫Vous voyez donc que cette
‫vérification ici est en fait une fonction asynchrone.
‫Il vérifiera donc un jeton, puis après cela, une
‫fois terminé,
‫il appellera la fonction de rappel que nous pouvons spécifier.
‫Maintenant, nous avons travaillé avec des promesses tout le
‫temps, et je ne veux pas vraiment casser ce schéma ici.
‫Et donc, nous allons en fait promettre cette fonction.
‫Donc en gros, pour lui faire revenir une promesse.
‫Et de cette façon, nous pouvons ensuite utiliser
‫async wait comme n'importe quelle autre fonction async que nous avons utilisée.
‫Donc, pour ce
‫faire, Node a en fait une fonction de promesse intégrée.
‫Tout ce que nous devons faire
‫pour l'utiliser est d'exiger le module util intégré.
‫Faisons-le tout en haut, en fait.
‫Cela va donc créer un objet appelé util, require...
‫D'accord, ça veut dire utilité.
‫Ce n'est pas ce que je voulais.
‫Cela signifie donc utilité.
‫Et puis là-bas, nous allons utiliser la méthode de promisify.
‫Mais comme nous n'allons utiliser que cette seule méthode, nous pouvons
‫en fait le faire plus facilement.
‫Ainsi, au lieu
‫de faire cela, nous pouvons simplement déstructurer cet objet et prendre
‫des promesses directement à partir de là.
‫Encore une fois, il s'agit simplement d'utiliser la déstructuration ES6.
‫D'accord, donc et maintenant c'est très facile à utiliser.
‫Tout ce que nous avons à faire est d'appeler la promesse.
‫Alors promettez, puis passez la fonction là-dedans.
‫Et donc maintenant, tout cela ici est une fonction
‫que nous
‫devons appeler, qui retournera ensuite une promesse.
‫Alors ici, nous appelons en fait la fonction.
‫Et cela renverra alors une
‫promesse, et nous pouvons donc l'attendre et stocker le résultat dans une variable.
‫Ainsi, la valeur de résultat de la
‫promesse sera en fait les
‫données décodées, donc la charge utile décodée de ce jeton Web JSON.
‫Alors laissez-moi l'appeler décodé ici.
‫D'accord.
‫Et nous pouvons attendre car nous avons déjà dit
‫que c'est une fonction asynchrone.
‫Et maintenant, juste pour voir que cela
‫fonctionne réellement, enregistrons également ces données décodées sur la console.
‫Et effectivement, on peut supprimer cette console. déconnectez-vous du jeton.
‫Celui-là dont nous n'avons plus besoin.
‫Essayons donc d'envoyer à nouveau cette demande, et oui, mais
‫cette fois en activant cet en-tête d'autorisation
‫afin que nous envoyions un jeton Web JSON avec la demande.
‫Alors ça l'a envoyé.
‫Et maintenant, en effet, nous avons accès aux
‫données, et donc, nous avons maintenant accès à la route protégée.
‫D'accord?
‫Mais ce que je voulais voir, c'est cet objet décodé ici.
‫Et donc ceci ici devrait être l'ID utilisateur.
‫Jetons donc un coup d'œil à cela dans Postman.
‫Donc 62a42.
‫Et donc, en effet, eh bien, où avons-nous cela?
‫Jetons un coup d'œil à Compass.
‫Et en effet, l'ID de cet utilisateur est ce 62a42.
‫Et cela signifie que nous avons en
‫fait notre charge utile correcte ici.
‫Donc, en gros, l'ID utilisateur correct.
‫Nous avons alors également l'horodatage de la date de
‫création et de la date d'expiration du jeton.
‫Donc ça marche.
‫Mais essayons maintenant de manipuler la charge utile de
‫ce jeton.
‫Alors copions-le ici à nouveau.
‫Mais ensuite, je vais au débogueur JWT.
‫Encore une fois, chez jwt. io.
‫Alors enlevons ça.
‫Et maintenant, ce que je vais faire, c'est modifier
‫certaines données ici et cela changera ensuite le jeton encodé ici,
‫que je pourrai ensuite copier.
‫Remplaçons donc simplement, en fait,
‫je vais simplement remplacer ces deux nombres ici par
‫quelque chose de différent.
‫Et donc, comme vous le voyez, cela a changé le jeton ici.
‫Et maintenant, je vais essayer d'accéder à
‫cette route protégée
‫à l'aide de ce jeton Web JSON manipulé.
‫D'accord, ça a du sens ?
‫Donc juste pour voir si cela fonctionne correctement.
‫Je copie donc
‫celui-ci ici maintenant et colle cet autre différent.
‫Et donc, si j'envoie maintenant cette demande, alors nous obtenons une erreur.
‫Tellement bon.
‫Ainsi, nous voyons que le nom de l'erreur est
‫JsonWebTokenError, et nous avons une signature invalide.
‫Tellement bon.
‫C'est exactement ce que nous recherchions.
‫C'est donc l'une des deux erreurs qui peuvent se produire.
‫L'autre est que le jeton a déjà expiré.
‫Donc celui-ci s'appelle JsonWebTokenError, et donc
‫en fait, allons de l'avant et gérons cette erreur maintenant.
‫Et la façon
‫dont nous pourrions le faire est d'ajouter un bloc try-catch ici.
‫Droit?
‫Donc juste après avoir fait ce code,
‫nous pourrions introduire un bloc
‫try, puis dans le catch, nous créerions ensuite des
‫erreurs qui seraient envoyées au client.
‫Maintenant, au lieu de procéder ainsi,
‫je souhaite en fait utiliser notre middleware global de gestion
‫des erreurs afin de le faire pour nous.
‫Nous n'aimons donc pas gérer les erreurs ici même
‫dans notre fonction middleware.
‫Au lieu de cela, nous le déléguons généralement au contrôleur d'erreur.
‫Et donc, faisons exactement la même chose ici.
‫Donc contrôleur d'erreur.
‫Et puis c'est en fait exactement la
‫même chose que nous avons avec nos autres erreurs ici.
‫Ainsi par exemple, l'erreur de validation venant de Mongoose,
‫donc d'une autre librairie.
‫Et maintenant, cette erreur provient en fait d'une autre
‫bibliothèque et elle a également son propre nom.
‫Alors allons-y.
‫Et c'est JsonWebTokenError.
‫D'accord.
‫Et donc, faisons très similaire ici.
‫Donc si. name
‫est celui-ci, alors error doit être égal à handle error.
‫D'accord.
‫Alors allons-y
‫et créons cette fonction, en fait, quelque part ici.
‫Et celui-ci est en fait extrêmement simple.
‫Tout ce qu'il fait est de prendre une
‫erreur, puis de renvoyer une nouvelle AppError.
‫D'accord?
‫Donc, dans
‫cette fonction de flèche ES6, comme j'espère que vous le savez, nous pouvons
‫écrire ces lignes simples où nous n'avons
‫même pas à spécifier les accolades ni le mot-clé return.
‫Cela retournera donc automatiquement
‫et implicitement tout ce que nous mettons ici.
‫Droit?
‫Et donc,
‫ce que nous voulons dire ici est simplement un jeton
‫invalide, veuillez vous reconnecter.
‫Et puis, le code d'erreur, comme avant,
‫est un 401 pour Unauthorized.
‫Maintenant, cela ne fonctionne, rappelez-vous, qu'en production.
‫Et donc, si nous faisions cela à nouveau maintenant,
‫nous obtiendrions exactement la même chose.
‫Et donc, revenons en fait ici et
‫exécutons cela en production.
‫Alors npm run start:production.
‫Ouais, juste comme ça.
‫Donc, si nous essayons
‫à nouveau maintenant, voyons si nous obtenons notre erreur.
‫Et en effet, nous le faisons.
‫Donc, si, en ce moment, un utilisateur en
‫production essaie d'accéder à notre application avec
‫un jeton invalide, eh bien, il n'obtient que ce message d'erreur.
‫D'accord?
‫C'est donc la première erreur que nous pouvons obtenir.
‫Mais un autre est que l'utilisateur essaie
‫d'accéder à l'application
‫avec un jeton déjà expiré.
‫Et donc, essayons maintenant de créer cette erreur.
‫Et pour ce faire, je vais
‫changer le temps qu'il faut pour que le jeton expire.
‫Donc en ce moment, nous avons 90 jours.
‫Mettons ça à, genre, cinq secondes.
‫D'accord.
‫Donnez-lui une sauvegarde.
‫Et maintenant, essayez de vous connecter à nouveau.
‫Alors gardons en fait celui-ci ici aussi.
‫Donc, dans les utilisateurs, puis connectez-vous.
‫Nous pouvons donc nous connecter, et cela nous donnera alors un
‫nouveau jeton, mais ce jeton n'est valable que cinq secondes.
‫Et donc, ces cinq secondes auraient dû s'écouler à ce stade.
‫Je vais donc maintenant copier ce jeton et essayer d'accéder à notre
‫route protégée à l'aide de ce jeton.
‫Alors collez-le ici.
‫Et maintenant, voyons ce que nous obtenons.
‫Et en fait, pour une raison quelconque, cela a fonctionné.
‫Jetons donc à nouveau un coup d'œil à notre débogueur JWT.
‫Et il est dit, créé le 2 mai, mais
‫n'expire que le 31 juillet.
‫Donc quelque chose s'est mal passé dans cette création de jeton, je suppose.
‫Et donc, changeons cela ici encore.
‫Et je vais juste en mettre cinq ici.
‫Et donc, ce cinq devrait alors
‫rester cinq millisecondes, ou je peux même, comme, mettre 5000,
‫ce qui devrait alors être cinq secondes.
‫D'accord.
‫Alors permettez-moi de l'enregistrer à nouveau afin de redémarrer le serveur.
‫Essayez à nouveau.
‫Alors reconnectez-vous ici.
‫D'accord.
‫Alors maintenant, tout ce
‫que nous avons à faire est d'attendre cinq secondes, et ce temps devrait déjà s'être écoulé à ce stade.
‫Collez-le ici à nouveau.
‫Et allons-y.
‫Et effectivement, nous obtenons une erreur.
‫Rappelez-vous maintenant qu'il s'agit essentiellement de
‫l'erreur standard que nous obtenons au cas où nous ne gérons
‫pas correctement cette erreur dans notre gestion des erreurs.
‫Droit?
‫Jetons donc un œil à l'erreur.
‫Et en fait, nous l'avons ici dans la console.
‫Voyons donc d'où cela vient.
‫Et oui, ça vient de cet endroit.
‫C'est donc le cas où nous avons une erreur inconnue.
‫Rappelez-vous, donc une erreur qui n'est pas marquée comme
‫une erreur opérationnelle, et donc nous
‫voulons la consigner.
‫Nous l'enregistrons donc ici, puis nous
‫envoyons ce message d'erreur
‫générique au client, donc celui que nous venons de
‫voir dans Postman.
‫Mais ici, nous avons en fait les détails de cette erreur.
‫Et donc, celui-ci porte le nom de TokenExpiredError.
‫D'accord.
‫Et donc, gérons maintenant celui-ci également.
‫Alors je le copie maintenant, puis je crée juste
‫un autre if ici.
‫Donc si l'erreur. name est égal à celui-ci, eh
‫bien, disons, handleJWTExpiredError
‫avec
‫la flèche.
‫Copions-le et mettons-le ici.
‫Et donc ceci, bien sûr, est très similaire à celui d'avant.
‫Votre jeton a expiré.
‫Veuillez vous reconnecter.
‫Et encore, avec un code d'erreur 401.
‫Bon, essayons encore.
‫Et donc, c'est exactement le message d'erreur
‫que nous devrions maintenant voir ici.
‫D'accord.
‫Et en effet, il l'est.
‫Super.
‫Finissons le processus ici
‫et démarrons-le en mode développeur, bien sûr.
‫Alors npm start,
‫et tout va bien.
‫Alors celui-ci, nous n'en avons plus besoin, alors fermons-le.
‫Ou en fait, corrigeons cette petite erreur ici, car en effet, nous
‫n'utilisons pas du tout cette erreur ici.
‫Alors débarrassons-nous en.
‫Et puis ici-bas, nous n'avons pas besoin de le transmettre là-bas.
‫Frais.
‫Bien entendu, nous devons également revenir à 90 jours.
‫D'accord.
‫Et
‫donc, juste pour être vraiment sûr, reconnectons-nous ici,
‫copions le
‫jeton et mettons-le ici.
‫Maintenant, ce processus ici de copier le jeton,
‫puis de le coller ici dans cet en-tête peut
‫sembler un peu étrange, et en fait, nous allons
‫corriger cela dans l'une
‫des futures vidéos afin que,
‫fondamentalement, ce processus se produise automatiquement.
‫Mais maintenant, ce qui est important, c'est qu'il est réellement
‫de retour au travail maintenant.
‫Nous pouvons donc effectivement nous débarrasser de cette console. connectez-vous ici et passez
‫à l'étape suivante.
‫Et nous pourrions en fait nous arrêter ici maintenant si nous le voulions.
‫Et encore une fois, la plupart des
‫tutoriels que vous allez découvrir s'arrêteraient en fait ici.
‫Mais ce n'est pas encore assez sûr pour l'instant.
‫Ainsi, par exemple, que se passe-t-il si l'utilisateur
‫a été supprimé entre-temps ?
‫Donc, le jeton existera toujours, mais si l'utilisateur
‫n'existe plus, alors nous ne
‫voulons pas le connecter, n'est-ce pas ?
‫Ou pire encore, que se passe-t-il si l'utilisateur a effectivement
‫changé son mot de passe après
‫l'émission du token ?
‫Eh bien, cela ne devrait pas non plus fonctionner, n'est-ce pas ?
‫Par exemple, imaginez que quelqu'un
‫a volé le jeton Web JSON à un utilisateur.
‫Mais ensuite, afin de
‫se protéger contre cela, l'utilisateur change son mot de passe.
‫Et donc, bien sûr, cet ancien jeton émis avant
‫le changement de mot de passe ne devrait plus être valide.
‫Il ne devrait donc pas être accepté d'accéder aux routes protégées.
‫Et donc, c'est le genre de choses que nous allons mettre en
‫œuvre ici dans les étapes trois et quatre.
‫La première chose à faire est donc de vérifier si
‫l'utilisateur existe toujours.
‫Et donc, celui-là devrait être le plus facile.
‫Alors disons simplement, Utilisateur. findById.
‫Et donc, c'est maintenant pourquoi nous avons
‫en fait l'ID dans la charge
‫utile, car nous pouvons maintenant utiliser cet ID
‫et interroger l'utilisateur en utilisant uniquement cet ID.
‫Donc décodé. identifiant.
‫D'accord?
‫Cela devrait donc trouver le nouvel utilisateur.
‫Et bien sûr, nous devons attendre cela,
‫puis le stocker dans une variable.
‫Je l'appelle le freshUser.
‫D'accord?
‫Parce que ce n'est pas vraiment un nouvel utilisateur.
‫C'est seulement lorsque nous en créons un.
‫Mais ce n'est pas vraiment nouveau, c'est vraiment
‫juste l'utilisateur basé sur l'ID décodé.
‫D'accord?
‫Et nous
‫pouvons le faire pour être sûr à 100% que l'ID
‫est réellement correct, car si nous l'avons
‫fait jusqu'à ce point du code ici, cela signifie que le processus
‫de vérification que nous avons précédemment, ici, a réussi.
‫Sinon, cela aurait provoqué une erreur qui
‫aurait alors empêché la fonction
‫de continuer.
‫Et donc, encore une fois,
‫ce processus de vérification ici est en charge de la vérification
‫si personne n'a modifié l'ID qui se
‫trouve dans la charge utile de ce jeton.
‫Et donc, à cause de cela,
‫nous pouvons être sûrs à 100% que l'utilisateur pour lequel
‫nous avons émis le JWT est exactement celui dont l'ID est maintenant à
‫l'intérieur de la charge utile décodée, donc celui-ci.
‫D'accord?
‫Le processus de vérification est donc vraiment essentiel.
‫C'est vraiment ce qui fait tout ce travail.
‫Quoi qu'il en soit, maintenant ce que nous devons faire est
‫de vérifier s'il y a réellement un freshUser.
‫Et sinon, eh bien, bien sûr, nous allons
‫retourner une nouvelle erreur.
‫Donc, s'il n'y a pas de
‫freshUser, revenez de ce middleware et appelez
‫le suivant avec une erreur.
‫C'est donc un modèle que nous avons vu
‫maintes et maintes fois à ce stade, n'est-ce pas ?
‫Le jeton n'existe donc
‫plus.
‫Et en fait, c'est l'inverse.
‫Donc effectivement, l'utilisateur
‫appartenant au token n'existe plus.
‫Droit?
‫Et puis, la 401.
‫D'accord.
‫Alors testons cela encore une fois.
‫Et créons en fait un nouvel utilisateur pour cela.
‫Alors testez simplement avec le même mot de passe afin que nous
‫utilisions toujours le même ici juste pour rendre
‫nos tests un peu plus faciles.
‫Et je sais que tous ces tests ici font que
‫la vidéo prend vraiment beaucoup de temps,
‫mais bien sûr, il est vraiment important que nous testions tout ce que
‫nous faisons, en particulier
‫dans un sujet aussi important que l'authentification.
‫J'utilise donc maintenant ce JWT ici, donc je le colle
‫ici, mais bien sûr, avant d'envoyer la demande, je vais continuer et
‫supprimer cet utilisateur tout de suite.
‫D'accord?
‫Encore une fois, supposons
‫que quelqu'un ait créé un utilisateur puis s'est connecté,
‫et disons qu'après un certain temps, l'utilisateur a été supprimé.
‫Mais entre-temps, quelqu'un aurait pu avoir accès à ce JWT
‫et
‫pourrait maintenant essayer de se connecter en tant
‫qu'utilisateur qui était, en fait, déjà supprimé.
‫Et donc, encore une fois, nous ne devrions pas laisser cela se produire.
‫Alors permettez-moi de supprimer cet utilisateur ici maintenant.
‫Et voilà.
‫Et donc, testons-le maintenant.
‫Et encore une fois, gardez à l'esprit
‫que l'utilisateur appartenant à l'ID qui se trouve dans cette charge utile n'est plus là.
‫Voyons donc.
‫Et en effet, nous obtenons ce message d'erreur que nous venons de créer.
‫Donc celui-là fonctionne aussi.
‫Et passons au dernier.
‫Donc, étape numéro quatre, vérifiez si l'utilisateur a récemment
‫changé son mot de passe.
‫Donc, en gros, après l'émission du jeton.
‫Et pour implémenter ce test, nous allons en fait créer
‫une autre méthode d'instance.
‫Donc en gros, une méthode qui
‫va être disponible sur tous les documents.
‫Les documents sont donc des instances d'un modèle.
‫D'accord?
‫Et nous le faisons
‫parce que nous avons besoin de beaucoup de code pour cette vérification.
‫Et donc, en fait, ce
‫code appartient au modèle User et pas vraiment au contrôleur.
‫D'accord?
‫Et donc, faisons cela
‫comme nous l'avons fait avant pour vérifier le mot de passe.
‫Donc, dans le modèle utilisateur, nous avons déjà
‫implémenté cette méthode d'instance statique correctPassword, vous vous souvenez ?
‫Et donc, créons-en maintenant un autre.
‫Donc userSchema. méthodes. mot de passe modifiéAprès.
‫Donc, fonction, et dans
‫cette fonction, nous passerons l'horodatage JWT.
‫Donc, fondamentalement, cet horodatage qui indique quand le
‫jeton a été émis.
‫Appelons donc cela JWTTimestamp.
‫D'accord.
‫Et par défaut, nous retournerons false à partir de cette méthode.
‫Et cela signifiera alors que l'utilisateur n'a pas changé
‫son mot
‫de passe après l'émission du token.
‫D'accord?
‫Mettons donc cela ici, renvoyons false, essentiellement par défaut.
‫D'accord.
‫Mais alors,
‫nous avons aussi if this, et rappelons-nous que dans une méthode d'instance,
‫le mot-clé this pointe toujours vers le document actuel.
‫Et donc, ici, nous avons accès aux propriétés.
‫Maintenant, nous devons en fait créer un champ dans notre schéma pour la
‫date à laquelle le mot de passe a été modifié.
‫Donc on n'a pas encore ça.
‫Ajoutons-le donc rapidement ici.
‫Donc passwordChangedAt, et le type de
‫celui-ci sera une date.
‫Maintenant, cette propriété passwordChangedAt ici sera
‫toujours modifiée, bien sûr, lorsque quelqu'un changera
‫le mot de passe.
‫Donc pour le moment, nous n'avons cette logique nulle part, et
‫donc nulle part nous ne définissons réellement cette propriété.
‫Et donc, la plupart des documents, donc la
‫plupart des utilisateurs, n'auront tout simplement pas cette propriété dans
‫leurs données, donc dans leur objet, n'est-ce pas ?
‫Et donc, bien sûr, nous devons tester cela.
‫D'accord?
‫Donc, si la
‫propriété passwordChangedAt existe, alors seulement nous voulons réellement faire la comparaison.
‫D'accord?
‫Mais sinon,
‫donc si passwordChanged n'existe pas, alors cela signifie que l'utilisateur n'a jamais
‫réellement changé le mot de
‫passe, et donc nous pouvons simplement retourner false.
‫Encore une fois, c'est notre valeur par défaut, ce
‫qui signifie que l'utilisateur n'a pas
‫modifié le mot de passe après cet horodatage.
‫D'accord.
‫Et
‫maintenant, juste pour commencer, connectons ceci à la console. passwordChangedAt, et bien sûr, le JWTTimestamp également, juste pour que
‫nous puissions
‫voir comment nous pourrions les comparer.
‫D'accord.
‫Et maintenant, nous
‫devons réellement créer un utilisateur qui possède cette propriété, d'accord ?
‫Et encore une fois, plus loin dans la section, lorsque
‫nous implémenterons la logique pour
‫changer le mot de passe, nous définirons ensuite cette propriété.
‫D'accord?
‫Mais maintenant,
‫nous allons le définir artificiellement ici lorsque nous créerons un nouvel utilisateur.
‫D'accord?
‫Mettons donc ça ici.
‫Et ici, n'importe quelle date, en fait, servira.
‫Disons donc le 30 avril 2019 ici.
‫Et cela devrait ensuite être analysé correctement dans MongoDB.
‫Essayons ça, voyons si ça marche.
‫Et cela n'a pas fonctionné.
‫Donc, il ne pouvait pas vraiment analyser la date, disons.
‫Et en fait, je dois commencer par l'année
‫puis le jour à la fin.
‫Donc 2019 puis 30 avril.
‫Essayez à nouveau.
‫Et donc vous voyez que maintenant cela fonctionne réellement.
‫Nous avons donc cette date analysée ici.
‫D'accord?
‫Maintenant, afin de voir
‫réellement le résultat de cela, nous devons bien sûr appeler cette méthode.
‫D'accord?
‫C'est donc ce que nous allons faire ici à l'étape quatre.
‫D'accord?
‫Et donc, rappelez-vous
‫que nous pouvons appeler cette méthode d'instance sur un document utilisateur.
‫Tellement fraisUtilisateur. ChangePasswordAfter, puis cet
‫horodatage.
‫C'est donc à décodé. iat, donc émis à, essentiellement.
‫D'accord.
‫Voyons donc simplement le résultat de cela.
‫Et donc, bien sûr, cela devrait maintenant, pas
‫ici, donc cela devrait maintenant enregistrer ces deux valeurs dans la console.
‫D'accord.
‫Maintenant, bien
‫sûr, je dois me connecter avec exactement cet utilisateur, donc avec
‫test, alors c'est parti.
‫Connexion.
‫Copiez à nouveau ce jeton ici.
‫Et encore une fois, nous allons
‫automatiser cela dans la prochaine vidéo, en fait.
‫D'accord.
‫Collez-le ici.
‫Et maintenant, nous obtenons en fait ce bogue ici.
‫J'ai donc mal orthographié ce nom de fonction ici.
‫Eh bien, copions-le simplement.
‫Essayez à nouveau.
‫Oh mec.
‫Qu'est-ce qui ne va pas maintenant ?
‫Et je vois que j'ai simplement oublié ce journal ici.
‫Donc encore une erreur stupide.
‫J'ai probablement vu celui-là venir.
‫Mais maintenant, nous y allons.
‫Tout a donc bien
‫fonctionné, et tout ce que nous
‫voulions vraiment voir pour l'instant, ce sont ces deux résultats.
‫Donc, nous avons essentiellement celui-ci ici ce
‫format de date, puis l'autre dans cet horodatage en millisecondes ou en
‫deuxième ici.
‫Et donc, nous devons maintenant convertir ce
‫mot de passeChangedAt également en un horodatage comme celui-ci.
‫D'accord?
‫Et donc, pour cela, créons une nouvelle variable.
‫Donc changé l'horodatage.
‫Et nous pouvons l'utiliser. mot de passeChangedAt. obtenir du temps.
‫D'accord?
‫Et donc,
‫c'est l'une des nombreuses fonctions de date que JavaScript nous donne.
‫D'accord.
‫Et maintenant, comparons rapidement ces deux-là
‫parce que nous ne sommes pas encore tout à fait prêts, en fait.
‫Alors envoyez-le juste pour voir les résultats ici.
‫Et donc ce que nous voyons ici essentiellement, c'est
‫que celui-ci ici est
‫maintenant, essentiellement, en secondes, et celui-ci en millisecondes.
‫C'est donc 1000 fois plus.
‫Et donc, nous savons que nous devons diviser
‫cela par 1000, puis analyser tout cela comme un entier.
‫Et pour cela, nous utilisons parseInt.
‫Donc, une autre fonction JavaScript disponible pour les nombres.
‫Et puis nous devons également spécifier la base.
‫Il s'agit donc d'un nombre en base 10.
‫D'accord?
‫Et maintenant, voyons encore une fois le résultat.
‫Et maintenant, cela semble beaucoup plus convivial.
‫D'accord.
‫Et donc, retournons maintenant notre résultat.
‫Et encore une fois, gardez à l'esprit que faux signifie pas changé.
‫D'accord?
‫Et non
‫modifié signifie essentiellement que le jour ou l'heure à laquelle le jeton a été
‫émis est inférieur à l'horodatage modifié.
‫D'accord?
‫Donc, à titre d'exemple ici,
‫disons que le jeton a été émis à l'instant 100.
‫Mais ensuite, nous avons changé le mot de passe, disons, au temps 200.
‫D'accord?
‫Et donc, nous
‫avons changé le mot de passe
‫après l'émission du jeton, et donc, c'est maintenant vrai.
‫D'accord?
‫Et c'est exactement ce sur quoi nous
‫voulons revenir ici, car faux
‫signifie pas changé, et donc vrai, bien sûr, signifie changé.
‫Et donc, c'est exactement ce que nous avons ici.
‫Mais maintenant, disons que le mot de passe a été
‫modifié pour la dernière
‫fois à 200, mais ce n'est qu'après cela
‫que nous avons émis le jeton, disons, à l'instant 300.
‫Et donc, 300, moins de 200 ?
‫Non, c'est faux.
‫Et donc, nous retournons false, ce qui signifie encore une fois non modifié.
‫Et donc, c'est pourquoi nous utilisons ce signe moins ici.
‫D'accord?
‫Revenons à notre contrôleur et utilisons-le réellement.
‫Donc, si le mot de passe a réellement été modifié, eh bien,
‫dans ce cas, nous voulons en fait une erreur.
‫Alors revenez ensuite, encore une fois, une nouvelle AppError.
‫Récemment...
‫Veuillez vous reconnecter.
‫D'accord.
‫Et encore une fois, codez 401.
‫D'accord.
‫Encore une fois, cela
‫retournera vrai si l'utilisateur a réellement changé son mot de passe.
‫Et donc, si tout cela ici est vrai,
‫eh bien, c'est exactement dans ce cas que nous
‫voulons que cette erreur se produise.
‫D'accord?
‫C'était donc en fait la dernière étape.
‫D'accord.
‫Donc, fondamentalement, si le code peut aller jusqu'à
‫la fin de ce code ici, alors seulement, la prochaine sera exécutée.
‫Et puis, avec next, nous passons au gestionnaire de
‫route suivant, ce qui signifie effectivement accorder l'accès
‫à cette route protégée.
‫Mettons ça ici.
‫Accordez l'accès à la route protégée.
‫D'accord?
‫Parce que c'est vraiment tout ce que fait ensuite.
‫Next nous amène au middleware
‫suivant, qui est donc généralement le gestionnaire de route
‫lui-même, donc celui qui renvoie les données qui étaient protégées.
‫D'accord.
‫Juste une dernière chose
‫que nous voulons faire ici est de mettre en fait toutes les données utilisateur sur la demande.
‫Nous pouvons donc simplement dire, req, donc demande, . user sera égal à
‫freshUser.
‫D'accord.
‫Et encore une
‫fois, bien sûr, le
‫code n'atteint jamais ce point ici que si tout est correct.
‫D'accord?
‫Et donc, ceci
‫ici pourrait alors être utile à un moment donné dans le futur.
‫Super.
‫Testons simplement cela une fois de plus.
‫Et fondamentalement, ce changement est dans le passé maintenant.
‫Et donc, ce jeton que nous avons ici, ou en
‫fait, j'aurais pu
‫réutiliser celui-ci au lieu de le réenregistrer.
‫Mais de toute façon, ce jeton a
‫été émis après le changement de mot de passe.
‫Et donc, ce jeton devrait maintenant fonctionner.
‫Alors reconnectons-nous et
‫essayons avec ce jeton.
‫Et en effet, nous avons accès.
‫Passons maintenant à Compass pour modifier cette date.
‫D'accord.
‫Mettons-le un mois plus tard.
‫Et donc, ce sera en fait
‫dans le futur, donc du moins, dans mon futur quand j'enregistrerai cette vidéo.
‫Bien sûr, vous le ferez plus tard.
‫Et donc, pour tester cela, veuillez mettre cela dans votre futur.
‫Donc dans le futur de la date où vous
‫regardez cette vidéo.
‫Donc, si je retourne
‫maintenant à Postman et me reconnecte, d'accord, donc si je me reconnecte maintenant et
‫essaie d'accéder à cette route, eh bien,
‫ce jeton sera émis, essentiellement, après
‫que le mot de passe ait été modifié.
‫Ou en fait avant que le mot de passe n'ait été modifié.
‫Alors, désolé pour cette confusion.
‫Le mot de passe a donc été changé
‫le 30 mai, mais ce token a été émis le 2 mai, et donc, avant.
‫Donc, en gros, c'est maintenant comme si l'utilisateur avait changé son mot
‫de passe après l'émission du jeton.
‫Et donc, c'est exactement la situation où nous ne voulons pas donner accès
‫à la route protégée.
‫Et donc, cela devrait maintenant refléter cela.
‫Et en effet, l'utilisateur a récemment changé de
‫mot de passe, veuillez vous reconnecter.
‫Super.
‫Donc ça marche maintenant.
‫Ainsi, notre middleware de protection est maintenant complètement implémenté.
‫Débarrassons-nous simplement de cette console. connectez-vous ici.
‫Je n'ai plus besoin de celui-là.
‫Et bien.
‫Alors récapitulons rapidement, et cette vidéo dure
‫très longtemps, un peu
‫plus longtemps que ce à quoi je m'attendais.
‫Mais il est vraiment
‫important de comprendre et d'expliquer comment
‫tout cela fonctionne et pourquoi c'est important.
‫Et donc, je préfère ça que de faire cette vidéo beaucoup plus courte.
‫Bien sûr, je pourrais juste écrire le code, mais alors vous ne comprendriez pas vraiment
‫ce qui se passe.
‫Donc cette partie nous l'avons déjà compris.
‫Ensuite, cette partie, je crois aussi,
‫c'est donc là que la vérification se produit,
‫donc essentiellement pour voir si la charge utile du
‫jeton n'a pas été manipulée par un tiers malveillant.
‫D'accord?
‫Et puisque nous
‫atteignons ensuite ce code ici, cela signifie que personne
‫n'a modifié le jeton Web JSON et, par conséquent, nous pouvons obtenir un nouvel utilisateur.
‫Donc, fondamentalement, nous pouvons obtenir l'utilisateur
‫actuel, appelons-le en fait currentUser.
‫Pourquoi pas?
‫Alors ici, ici et aussi ici.
‫D'accord?
‫Nous pouvons donc obtenir le
‫currentUser à partir de cet ID qui vient d'être décodé à partir de la charge utile.
‫Maintenant, si l'utilisateur actuel n'existe pas, c'est
‫donc ce que nous testons ici, eh bien,
‫dans ce cas, nous ne voulons pas donner accès
‫à la route
‫et créer à la place cette nouvelle erreur.
‫Mais si l'utilisateur existe, eh bien, nous
‫arrivons au point numéro
‫quatre, où nous vérifions ensuite si un changement de mot de
‫passe s'est produit après l'émission du jeton, n'est-ce pas ?
‫Et si c'est le cas, encore une fois, nous créons une nouvelle erreur.
‫Et si ce n'est pas le cas, eh bien, nous
‫allons jusqu'à la fin
‫de la fonction middleware, où
‫nous attribuons ensuite le currentUser à la requête. user afin que nous puissions ensuite l'utiliser
‫dans une prochaine fonction middleware.
‫D'accord?
‫Car rappelez-vous,
‫cet objet de requête, c'est celui qui voyage,
‫en gros, de middleware en middleware.
‫Et donc, si nous voulons transmettre
‫des données d'un middleware au
‫suivant, nous pouvons simplement mettre des éléments sur l'objet
‫de requête, et ces données seront ensuite disponibles à un moment ultérieur.
‫D'accord.
‫Alors c'est tout.
‫Il s'agit
‫essentiellement d'un algorithme de protection de
‫route très sophistiqué et très complet, mais je pense qu'il est vraiment important de
‫le faire aussi bien que possible.
‫Quoi qu'il en soit, je suis content de voir que vous êtes
‫arrivé à la fin de cette grosse vidéo,
‫et je vous verrai dans la prochaine.