‫- : Ainsi, au cours des dernières
‫vidéos, nous avons permis à un utilisateur de réinitialiser son
‫mot de passe puis d'en créer
‫un nouveau, mais maintenant nous
‫voulons également permettre à un utilisateur connecté de simplement mettre à jour
‫son mot de passe sans avoir à l'oublier,
‫et ainsi de suite sans tout ce processus de réinitialisation.
‫Alors, construisons cela maintenant.
‫Et, comme
‫avant, faisons-le dans notre contrôleur d'authentification.
‫Alors, exportez. mettre à jour le mot de passe.
‫D'accord, et comme toujours,
‫nos trois paramètres Middleware ici, et d'accord.
‫Rappelez-vous maintenant que cette fonctionnalité de mise à jour du mot de
‫passe est uniquement destinée aux utilisateurs
‫connectés, mais nous avons toujours besoin que l'utilisateur transmette son mot de passe
‫actuel, afin de confirmer
‫que cet utilisateur est bien celui qu'il prétend être.
‫Donc, juste par mesure de sécurité, car
‫imaginez que quelqu'un trouve votre ordinateur ouvert et puisse ensuite changer les
‫mots de passe sur les sites que vous avez actuellement
‫ouverts sans être
‫à nouveau invité à saisir un mot de passe.
‫Et cela vous déconnecterait donc
‫de toutes vos applications existantes, ce qui,
‫bien sûr, serait une expérience terrible.
‫Et donc, par mesure de sécurité, nous devons toujours
‫demander le mot de passe actuel avant de le mettre à jour, d'accord.
‫Et, dans cet esprit, exposons toutes
‫les étapes que nous
‫devons suivre pour implémenter cette fonctionnalité comme avant.
‫Donc, tout d'abord, nous devons obtenir l'utilisateur de
‫la collection, en gros.
‫Ensuite, nous devons vérifier si
‫le mot de passe affiché est correct.
‫Droit.
‫Ensuite, troisièmement, donc si le mot de passe est correct,
‫mettez à jour le mot de passe.
‫Et enfin, nous devons à nouveau connecter l'utilisateur, donc
‫essentiellement pour renvoyer le jsonwebtoken à l'utilisateur, maintenant connecté avec le
‫nouveau mot de passe qui vient d'être mis à jour.
‫D'accord, et tout cela est en fait très similaire à
‫ce que nous avons déjà
‫fait auparavant, et je vous laisse
‫donc celui-ci comme un défi, d'accord ?
‫Alors, s'il vous plaît essayez d'aller de l'avant et implémentez cela par vous-même,
‫et si vous en avez besoin, vous pouvez bien sûr
‫jeter un œil au code
‫que nous avons écrit auparavant, mais essayez vraiment d'écrire le
‫code par vous-même sans trop copier, d'accord ?
‫Vous pouvez donc jeter un œil au reste du code
‫pour voir comment cela fonctionne, mais ne vous contentez pas de le copier, d'accord ?
‫Parce qu'alors tu n'apprendras pas vraiment, d'accord.
‫Alors, mettez la vidéo en pause ici, et je vous verrai dans
‫une seconde avec ma solution.
‫D'accord, j'espère que vous avez réussi à implémenter cela
‫et à le faire fonctionner, c'est ainsi que j'ai procédé.
‫Donc, comme toujours, nous créons une nouvelle variable utilisateur, et là nous
‫attendons le résultat de faire User. findById, et maintenant
‫d'où vient réellement cet ID ?
‫Eh bien, rappelez-vous encore que ce mot de passe de mise à
‫jour est uniquement pour les utilisateurs authentifiés, donc pour les
‫utilisateurs connectés, et donc, à ce stade, nous aurons déjà
‫l'utilisateur actuel sur notre objet de demande.
‫D'accord, cela vient donc du middleware de protection.
‫Donc, req. utilisateur. id, puis rappelez-vous
‫que nous devons demander explicitement le mot de passe, d'accord ?
‫Parce qu'il n'est, par défaut, pas inclus dans la sortie.
‫Alors, on a défini ça sur le schéma, tu te souviens ?
‫Et, nous avons en fait besoin
‫de ce mot de passe parce que maintenant nous voulons le
‫comparer avec celui qui est stocké
‫dans la base de
‫données, et pour cela, comme avant, nous allons utiliser cet objet d'instance
‫que nous avons quelque part ici.
‫Oui, donc correctPassword, qui est disponible sur
‫tous les documents utilisateur,
‫donc il prend d'abord le mot
‫de passe candidat, puis le mot de passe utilisateur réel, d'accord.
‫Oh, et maintenant cela
‫me donne cette erreur car, bien sûr, je ne
‫l'ai pas encore déclaré comme fonction asynchrone.
‫Donc, async, et avant de
‫l'oublier, enveloppons-le également dans la fonction catchAsync ici.
‫Quoi qu'il en soit, comme
‫avant, nous voulons essentiellement créer une erreur ici
‫si le mot de passe actuel n'est pas correct, et
‫donc, écrivons cela dans le code.
‫Donc, sinon utilisateur. correctPassword, puis
‫le mot de passe candidat
‫se souvient, et donc celui-ci va
‫être dans un corps, dans une propriété que nous allons appeler passwordConfirm.
‫D'accord, puis comme deuxième argument le mot de passe réel, donc
‫c'est un utilisateur. le mot de passe.
‫Et puis, rappelez-vous qu'il s'agit d'une fonction asynchrone,
‫et nous devons donc également l'attendre ici.
‫Bien, donc au cas où le mot de passe n'est pas
‫correct, comme toujours, nous créons une nouvelle erreur ici.
‫Donc, nouvelle AppError, et cette fois, nous
‫disons que votre mot de passe actuel est incorrect,
‫puis le code d'état 401 pour non autorisé.
‫Très bien, super.
‫Maintenant, si nous arrivons à ce point dans le
‫code, donc fondamentalement si le mot de passe est également correct, alors
‫nous pouvons réellement mettre à jour le mot de
‫passe, et comment le faisons-nous ?
‫Eh bien, très simple, nous l'avons fait avant.
‫Tout ce que nous disons est utilisateur. le mot de passe est égal à req. corps. mot de passe, puis
‫la même chose, bien sûr, pour la confirmation du mot de passe.
‫D'accord, et la validation se fera automatiquement par le validateur
‫que nous avons spécifié sur le schéma, et cela se fera
‫une fois que nous l'aurons réellement enregistré.
‫Donc, nous attendons l'utilisateur. enregistrer, et donc cette fois nous
‫ne désactivons pas la validation car, bien sûr, nous
‫voulons que la validation se produise, donc comme je l'ai
‫dit précédemment, nous voulons vérifier que la confirmation du
‫mot de passe est bien le même que
‫le mot de passe, n'est-ce pas ?
‫Bon.
‫Et maintenant, juste pour être vraiment sûr que vous compreniez pourquoi nous n'avons
‫pas fait quelque chose comme user. findByIdAndUpdate.
‫Alors, pourquoi n'avons-nous pas fait comme ça ?
‫Et, je sais que j'en ai déjà parlé plusieurs fois, mais
‫je veux que vous compreniez à cent pour cent pourquoi
‫nous ne pouvons pas utiliser cette mise à jour,
‫et c'est pour deux
‫raisons, alors permettez-moi de revenir à notre modèle.
‫Donc, le premier
‫est que cette validation ici ne va pas fonctionner, d'accord ?
‫Et c'est essentiellement parce que cela. le mot de passe n'est
‫pas défini lors de la mise à jour, donc lorsque nous utilisons find by
‫ID et update, car en interne,
‫dans les coulisses, Mongoose ne garde pas vraiment l'objet actuel en
‫mémoire, et donc, ici, cela ne va pas fonctionner.
‫Et, comme je l'ai dit, j'en ai déjà
‫parlé auparavant, donc c'est en fait écrit ici aussi, d'accord ?
‫Mais, il est vraiment important de garder à l'esprit de ne pas utiliser
‫la mise à jour pour quoi que ce soit en rapport avec les mots de passe, d'accord ?
‫Donc, celui-ci ne
‫fonctionnera pas, et ces deux
‫middlewares pré-enregistrés ne fonctionneront pas non plus.
‫Donc, si nous utilisions simplement update pour mettre à jour
‫le mot de passe, alors ce mot de passe
‫ne serait pas crypté,
‫ce qui est ce premier middleware, et puis
‫aussi, l'horodatage passwordChangedAt ne serait pas non plus défini, d'accord ?
‫Donc, rien de tout cela ne
‫fonctionnerait, et encore une fois, nous devons vraiment le faire comme ça.
‫Remettons ça ici.
‫Et maintenant, (marmonne), nous avons connecté
‫l'utilisateur et renvoyé le jeton au client.
‫Maintenant, ce serait en fait la quatrième fois
‫que nous ferions le même code,
‫donc fondamentalement ce morceau de code,
‫et donc, c'est maintenant très rapidement refactorisé cela
‫dans sa propre fonction.
‫Or, ce code n'est en fait pas le même partout.
‫Donc, ici, nous avons envoyé le code
‫d'état 400, et nous n'envoyons
‫pas l'utilisateur, mais ici, dans le gestionnaire d'inscription, nous avons en
‫fait un code d'état différent, et
‫nous avons également envoyé l'utilisateur au client, d'accord ?
‫Et donc, faisons en sorte que notre fonction garde cela à l'esprit.
‫Alors, créons une fonction ici, créons et envoyons un jeton,
‫puis les arguments dont nous avons
‫besoin ici sont l'utilisateur car c'est là
‫que l'ID est stocké.
‫Ensuite, nous voulons également
‫le code d'état, et bien sûr, nous devons avoir accès à
‫l'objet de réponse afin de pouvoir réellement renvoyer
‫une réponse au client, d'accord ?
‫Et donc, fondamentalement, ce dont nous avons besoin maintenant, c'est de ce code.
‫Alors, copions-le, mettons-le ici,
‫puis remplaçons les variables non pertinentes.
‫Donc, l'utilisateur est simplement appelé utilisateur, donc juste comme ça,
‫et ici, la même chose.
‫Donc, pas
‫un nouvel utilisateur, et puis ici nous remplaçons cela par le
‫code d'état, donc celui qui entre dans notre fonction, et
‫donc je suppose que c'est en fait ça.
‫Alors, allons-y maintenant et remplaçons-le,
‫donc createSendToken, et ici l'utilisateur s'appelle le newUser, le code
‫d'état est 201,
‫puis bien sûr l'objet de réponse.
‫Bon, maintenant nous pouvons nous débarrasser de ce code,
‫et copions-le simplement.
‫Très bien, donc dans la connexion, nous avons bien sûr également envoyé
‫un jeton, mais cette fois, l'utilisateur est en fait appelé utilisateur et le
‫code d'état est 200.
‫Et maintenant, copions celui-ci.
‫Donc, le suivant devrait être ici, et réinitialiser le mot de
‫passe, et ici c'est
‫en fait le même, donc le nom est
‫user et code 200, et maintenant, enfin, ici c'est aussi le même.
‫Et ainsi, cela termine notre fonction de mise à jour du mot de passe.
‫Maintenant, pour que cela fonctionne,
‫nous devons bien sûr implémenter la route ici aussi dans
‫notre routeur utilisateur.
‫Alors, routeur. patch, et nous allons faire un patch
‫parce que nous sommes en train de changer, donc nous
‫manipulons le document utilisateur, et c'est donc à cela que sert patch.
‫Et l'itinéraire s'appelle updateMyPassword.
‫Donc, mon mot de
‫passe car il est pour l'utilisateur actuellement connecté, et rappelez-vous, encore une
‫fois, cela ne fonctionne que pour les
‫utilisateurs connectés, et nous devons donc utiliser authController. protect, qui placera également l'objet
‫utilisateur sur un
‫objet de demande, d'accord ?
‫Alors, protégez, puis authController, mettez à jour le mot
‫de passe que nous venons de créer, d'accord.
‫Et donc, allons-y maintenant et testons ça, d'accord ?
‫Alors, copions cette route ici, donc UpdateMyPassword, et
‫maintenant ce que nous
‫devons envoyer dans le corps, ce sont ces trois mots de
‫passe en fait, donc c'est
‫essentiellement le passwordCurrent, et pour l'instant je les laisse vides,
‫je veux simplement
‫mettre le champ noms ici pour le moment.
‫Donc, passwordCurrent puis juste le mot de passe, qui
‫est fondamentalement le
‫nouveau, puis, bien sûr, passwordConfirm.
‫D'accord, et maintenant nous devons nous connecter en tant
‫qu'utilisateur car rappelez-vous, cela ne fonctionne
‫que si l'utilisateur est déjà connecté, d'accord.
‫Et donc, faisons-le avec l'administrateur ici.
‫Et ceci est, devrait être toujours le mot de passe actuel,
‫et en effet, nous sommes maintenant connectés.
‫Et rappelez-vous que ce jeton est maintenant
‫stocké dans la variable d'environnement
‫JWT, et donc, ici, afin de
‫nous authentifier, utilisons-le comme nous le faisions auparavant.
‫Ainsi, dans cet onglet d'autorisation, nous sélectionnons Bearer
‫Token, puis il pré-remplira automatiquement
‫cette variable JWT.
‫D'accord, et c'est donc de là que
‫va provenir l'ID utilisateur, tu te souviens ?
‫Quoi qu'il en soit, spécifions maintenant le mot de passe actuel, donc pass1234, puis
‫disons nouveau mot de passe, d'accord ?
‫Copiez-le et collez-le ici,
‫mais en fait encore une fois, je
‫veux commencer par le tester avec une confirmation
‫de mot de passe erronée, juste pour voir
‫si notre validation fonctionne toujours, et maintenant la route
‫n'est pas définie, mais c'est simplement parce que nous utilisons le mauvais verbe ici.
‫Bien sûr, il doit être patché.
‫Essayons à nouveau, mais maintenant
‫nous obtenons que votre mot de passe actuel est faux, mais en fait
‫ce n'est pas le cas, donc il est en fait correct.
‫Donc, quelque chose ne va pas avec notre code, alors
‫essayons de jeter un œil ici.
‫Et oui, donc voici en fait
‫le problème car nous ne voulons pas comparer ou confirmer le mot de passe,
‫bien sûr, mais avec le mot de passe actuel.
‫D'accord, c'est juste un bug stupide, d'accord, et maintenant
‫ça devrait fonctionner.
‫Donc, bien sûr, nous voulons comparer le mot de passe
‫actuel avec celui qui est
‫actuellement stocké dans la base de données, d'accord.
‫Alors, essayons à nouveau,
‫et c'est donc l'erreur de validation que nous recherchions, donc les
‫mots de passe ne sont pas
‫les mêmes car, en effet, ils ne le sont pas.
‫Et maintenant, avant de mettre à jour le mot
‫de passe, examinons simplement Compass ici.
‫Mettons-le à jour ici rapidement, et donc,
‫pour le moment, c'est le mot de passe.
‫Donc, en terminant ici, c'est pW1i, d'accord ?
‫Et donc, mettons à jour le mot
‫de passe maintenant et voyons à quoi il ressemblera après, d'accord ?
‫Donc, maintenant, tout devrait être correct.
‫Et, en effet, nous obtenons notre succès et notre jeton, très bien.
‫Alors, confirmons cela ici rapidement, et,
‫en effet, vous voyez que le mot
‫de passe a changé et
‫aussi l'horodatage actuel, donc l'heure à laquelle j'enregistre cette vidéo.
‫Très bien, et maintenant, comme avant,
‫faisons ce test ici.
‫Donc, essentiellement, stocker le jeton en tant que variable d'environnement.
‫Donc, juste pour que tout fonctionne vraiment ici dans Postman.
‫D'accord, gardons cela en fait, mettons
‫à jour le mot de passe de l'utilisateur actuel pour le rendre vraiment
‫explicite, et oui, je pense que c'est tout.
‫Je pense que c'est tout ce que nous devons faire pour
‫mettre à jour le mot de passe d'un utilisateur.
‫Ensuite, nous mettrons en œuvre la mise à jour des autres données utilisateur, donc
‫des choses comme les e-mails ou les mots de passe.