‫- : Dans cette conférence, nous allons permettre
‫à l'utilisateur actuellement connecté de manipuler ses données d'utilisateur.
‫Et maintenant, en implémentant les mises à jour
‫des utilisateurs, nous quittons vraiment le domaine de l'authentification et
‫nous nous dirigeons davantage vers de vrais trucs liés aux utilisateurs, d'accord ?
‫Et donc au lieu d'utiliser le contrôleur d'authentification maintenant,
‫implémentons cette fonctionnalité de mise à jour
‫directement dans leur userController.
‫D'accord, nous
‫avons donc un tas de gestionnaires, donc
‫d'itinéraires, qui ne sont pas vraiment implémentés ici, d'accord ?
‫Mais laissons-les de côté pour le
‫moment et créons notre nouvelle fonction de gestionnaire ici.
‫Et celui-ci s'appellera updateMe.
‫Et encore une fois, c'est updateMe car c'est pour
‫mettre à jour l'utilisateur actuellement authentifié.
‫Plus tard, nous implémenterons alors également
‫cette fonction updateUser ici, mais il s'agit alors pour un administrateur
‫de mettre à jour toutes les données de l'utilisateur, tandis que
‫l'utilisateur lui-même ne peut mettre à jour, pour l'instant du moins, que
‫le nom et l'adresse e-mail.
‫Alors, demande, réponse, et ensuite.
‫(claquement du clavier) Et nous le faisons réellement, donc la
‫mise à jour des données utilisateur, d'une manière différente de la
‫mise à jour du mot de passe utilisateur, eh bien parce
‫que généralement dans une application Web typique, c'est toujours
‫ainsi que cela se fait.
‫Ainsi, vous avez généralement un
‫endroit où vous pouvez mettre à jour
‫votre mot de passe, puis un autre endroit où vous
‫pouvez mettre à jour les données sur l'utilisateur ou le compte lui-même.
‫Et donc ici, nous suivons simplement ce modèle.
‫Alors encore une fois, commençons par exposer nos étapes.
‫Et la première chose que nous
‫voulons faire ici est de créer une erreur
‫si l'utilisateur essaie de mettre à jour le mot de passe.
‫Donc, créez une erreur si l'utilisateur publie essentiellement des
‫données de mot de passe.
‫Mais sinon, il suffit de mettre à jour le document utilisateur.
‫Si simple, et commençons bien sûr par
‫le premier.
‫Bien sûr, il y aura un
‫corps où nous allons transmettre les données, et
‫donc si sur ce corps il y a des données sur le mot de
‫passe, ou une confirmation de mot de passe...
‫(claquement des touches)
‫Validez.
‫Eh bien, dans ce cas, nous voulons revenir immédiatement et
‫créer une nouvelle erreur Apperror.
‫Oh et je suppose que nous ne l'avons pas encore mis en œuvre
‫ici, ou que nous ne l'avons
‫pas encore requis, alors prenons-le à partir d'ici.
‫Donc AppError...
‫Ce n'est
‫pas ici, donc le userController...
‫Alors AppError, c'est parti.
‫Donc 'Cet itinéraire n'est pas pour les mises à jour de mot de passe.
‫'Veuillez utiliser /updateMYPassword. ' Donc, en
‫gros, l'itinéraire que nous avons spécifié auparavant.
‫Alors mettez à jourMYPassword.
‫Et puis aussi, un code 400 pour une mauvaise demande.
‫Et essayons celui-ci tout de suite.
‫Et pour cela, juste
‫deux choses, nous devons d'abord renvoyer
‫une réponse, alors disons res. status(200) pour ok, puis json,
‫ajoutez le
‫statut en tant que succès.
‫Et plus tard, nous enverrons également l'utilisateur mis à jour,
‫mais laissons cela pour plus tard.
‫Voilà donc la réponse, et maintenant nous
‫devons bien sûr également ajouter cette route à notre utilisateur Router.
‫C'est donc bien sûr similaire à mettre à jour
‫mon mot de passe, donc routeur, et bien sûr
‫un
‫correctif, /updateMe, là encore, c'est une route protégée
‫afin que seul l'utilisateur actuellement authentifié puisse mettre à jour les
‫données de l'utilisateur actuel.
‫Et donc tout cela est bien sûr vraiment sécurisé, encore
‫une fois parce que l'ID de l'utilisateur qui va être mis à jour
‫vient de la demande. utilisateur, qui
‫a été défini par ce middleware de protection ici, qui à son
‫tour a eu l'idée du jeton Web json, et puisque
‫personne ne peut changer l'ID dans ce jeton Web
‫json sans connaître le secret, nous savons
‫que l'ID est alors sûr à cause de ça.
‫Et donc à cause de cela, tout ici est en sécurité.
‫Donc, userController. Tiens moi au courant.
‫Maintenant d'accord...
‫Alors testons cela maintenant.
‫Allez-y et copiez-le à nouveau.
‫Et tout d'abord, définissons l'autorisation.
‫Encore une fois à partir du Bearer Token et
‫bien sûr avec cette variable d'environnement.
‫Il doit également s'agir d'une demande de correctif
‫et nous devons spécifier un corps.
‫Et je veux commencer par le tester, provoquant
‫cette erreur bien sûr, et donc
‫spécifions un mot de passe,
‫puis un nom.
‫Disons donc que c'est le nom que nous voulons mettre à
‫jour, alors enregistrons-le ici.
‫Et en fait, c'est bien sûr dans le dossier Utilisateurs.
‫Données d'utilisateur.
‫Et en fait, créons un nouveau
‫dossier ici et mettons les éléments liés à l'authentification
‫dans son propre dossier.
‫Donc ici, nous
‫créons un nouveau dossier et l'appelons Authentification.
‫Ce n'est pas correct.
‫AH-PUIS-TICATION.
‫(rires) Alors c'est tout.
‫Le mot de passe est donc lié à l'authentification,
‫à la réinitialisation du mot de passe, à l'oubli du mot de passe, à
‫la connexion et à la déconnexion.
‫Alors, fermons ces deux-là, et maintenant
‫connectez-vous en tant que, ou créons en
‫fait un nouvel utilisateur.
‫Alors inscrivons-nous ici, en
‫tant qu'utilisateur normal, afin que nous puissions nous débarrasser de ces deux là.
‫Et maintenant, je l'appelle simplement, eh bien, teste à nouveau, d'accord ?
‫Et jetons un coup d'œil aux utilisateurs que nous avons actuellement
‫dans notre base de données.
‫Nous avons donc hello et
‫admin, et utilisons donc maintenant test.
‫Et je suis toujours à nouveau, en utilisant le même mot
‫de passe pour le rendre vraiment facile.
‫Très bien, nous devons également donner le nom, appelons-le
‫simplement J ici.
‫Et maintenant, en effet, nous obtenons notre jeton, et
‫nous sommes déjà connectés, et
‫donc maintenant, lorsque nous mettons à jour
‫l'utilisateur, cela devrait être pour cet utilisateur qui vient d'être connecté.
‫Je n'essaie donc pas de mettre à jour
‫et bien sûr, aucune mise à jour n'est encore implémentée et cela ne fonctionnera donc pas.
‫Tout ce que je veux voir, c'est l'erreur qui devrait
‫se produire car j'ai spécifié cette propriété de mot de passe ici sur le corps.
‫Essayons donc.
‫Et ici, nous obtenons cette sorte d'erreur d'apparence étrange, mais je suppose
‫que c'est simplement parce que nous n'avons pas réellement
‫mis à jour la
‫route ici, alors rappelez-vous que je viens de copier une route, donc
‫l'URL, et de la coller ici.
‫Mais bien sûr, il doit être updateME.
‫Essayons donc à nouveau.
‫Et maintenant, nous obtenons en fait cette erreur que nous avons spécifiée.
‫"Cet itinéraire n'est pas destiné aux mises à jour de mots de passe.
‫"Veuillez utiliser /updateMyPassowrd. " Tellement
‫génial, cette partie fonctionne, et
‫cela fonctionne aussi que nous devons être authentifiés.
‫Parce que disons que nous n'avons pas d'authentification, et
‫donc disons que : No Auth.
‫Et alors essayons à nouveau maintenant.
‫Et donc effectivement, « Vous n'êtes pas connecté !
‫"Veuillez vous connecter pour avoir accès. " Alors
‫juste pour vous prouver que notre authentification
‫fait aussi son travail ici.
‫Mais bien sûr, nous voulons notre Bearer
‫Token, et maintenant nous obtenons cette autre erreur.
‫Super, alors allons-y maintenant,
‫implémentons le reste des fonctionnalités du gestionnaire updateMe.
‫Donc mettre à jour le document utilisateur, et nous pourrions essayer
‫de le faire avec user. en sécurité.
‫Donc, comme avant, obtenir l'utilisateur, puis mettre à
‫jour les propriétés, puis à la fin,
‫enregistrer le document.
‫Mais le problème avec cela est qu'il y a
‫des champs qui sont obligatoires que nous ne mettons pas à
‫jour, et à cause
‫de cela, nous allons générer une erreur.
‫Et donc juste pour vous démontrer rapidement,
‫laissez-moi faire cela.
‫D'accord, donc très rapidement, amener l'utilisateur ici.
‫Alors findbyId, donc demande. utilisateur comme nous le savons déjà, . identifiant.
‫Et puis disons, utilisateur. name = 'Jonas' puis attendez
‫l'utilisateur. enregistrer.
‫Mais encore une fois, vous voyez que cela nous donnera alors une erreur.
‫Mais pour l'instant, déclarons-le aussi bien sûr
‫comme une fonction asynchrone.
‫Et bien.
‫Alors testons-le maintenant, mais
‫nous devrions nous attendre à voir une erreur maintenant.
‫Alors bien sûr débarrassons-nous de celui-ci, et
‫en effet nous obtenons : "Veuillez confirmer votre mot de passe".
‫Et c'est parce que passwordConfirm est un champ obligatoire mais nous
‫ne l'avons bien sûr pas spécifié.
‫Et donc la méthode sûre n'est pas vraiment la
‫bonne option dans ce cas.
‫Donc, à la place,
‫nous pouvons maintenant utiliser findById et mettre à jour.
‫Nous ne pouvions donc pas l'utiliser auparavant pour toutes les raisons
‫que je vous ai expliquées plusieurs fois maintenant.
‫Mais maintenant, puisque nous ne traitons pas
‫de mots de passe, mais uniquement de ces données non sensibles comme le
‫nom ou l'e-mail, nous pouvons maintenant utiliser findById et mettre à jour.
‫Alors, débarrassons-nous de cela.
‫Appelons-le également ici updateUser.
‫Et puis ici, nous devons transmettre non seulement l'ID, mais
‫aussi les données qui doivent être mises à
‫jour, puis quelques options.
‫Donc les données, appelons-les pour l'instant x ici, et je
‫vous explique pourquoi dans
‫une seconde, puis les options que nous voulons transmettre.
‫Et c'est comme avant, la nouvelle
‫option définie sur true, de sorte qu'elle renvoie le
‫nouvel objet, donc fondamentalement
‫l'objet mis à jour au lieu de l'ancien.
‫Et les runValidators sont également définis sur true.
‫Car effectivement nous voulons que les modèles valident notre document.
‫Ainsi, par exemple, si nous saisissons une adresse e-mail invalide, cela devrait
‫être détecté par le validateur et renvoyer une erreur.
‫Maintenant, pourquoi est-ce que je mets x ici, et pas simplement une demande. corps?
‫Et bien c'est parce qu'en fait on ne veut
‫pas mettre à jour tout ce qui est dans
‫le corps, parce que disons que l'utilisateur met, dans le corps,
‫le rôle par exemple.
‫Nous pourrions avoir un corps. rôle défini sur admin par exemple,
‫ce qui permettrait alors à tout utilisateur
‫de changer le rôle, par exemple, en administrateur.
‫Et bien sûr, cela ne peut pas être autorisé.
‫Ou l'utilisateur peut également modifier son jeton de réinitialisation,
‫ou lorsque ce jeton de réinitialisation expire,
‫et tout cela ne devrait bien sûr pas être autorisé.
‫Donc, faire quelque chose comme ça serait
‫bien sûr une énorme erreur.
‫Et donc nous devons nous assurer que l'objet
‫que nous passons ici, donc encore une
‫fois cet objet qui contiendra les données qui vont être
‫mises à jour, ne
‫contient que le nom et l'email, car pour l'instant ce
‫sont les seuls champs que nous voulons autoriser
‫à mettre à jour .
‫Et donc, en gros, nous voulons filtrer le corps
‫pour qu'à la fin, il ne contienne que le nom et l'e-mail
‫et rien d'autre.
‫Donc, si l'utilisateur essaie de changer de rôle, celui-ci sera
‫alors filtré afin qu'il
‫ne trouve jamais son chemin vers notre base de données.
‫Donc, ce que nous voulons faire, c'est essentiellement créer une
‫variable et disons
‫filteredBody, puis nous allons créer une fonction dans une seconde, mais
‫utilisons-la déjà ici, juste pour que vous
‫voyiez comment cela va fonctionner.
‫Et puis ici
‫nous passons les données, donc l'objet que
‫nous voulons filtrer, donc req. body, car c'est là que se
‫trouvent toutes les données, puis nous passons quelques arguments.
‫Un pour chacun des champs que nous voulons conserver
‫dans l'objet.
‫Nous souhaitons donc conserver le champ appelé
‫nom, et le champ appelé email.
‫Et encore une fois, un peu plus tard, nous pourrions alors ajouter plus de
‫champs ici, par exemple plus tard, nous pourrions
‫permettre à l'utilisateur de télécharger une image.
‫Et bien sûr que nous devons également mettre à jour
‫dans la base de données.
‫Mais pour l'instant, tout ce que
‫nous voulons garder dans le corps est le nom et l'e-mail et filtrer tout le reste.
‫Et donc ici, utilisons maintenant filteredBody, au lieu
‫de x bien sûr.
‫Et donc maintenant, ce que nous devons
‫faire, c'est implémenter réellement cette fonction qui s'occupera de filtrer l'objet.
‫Alors faisons-le ici.
‫FilterObj,
‫qui prendra un objet puis
‫les autres paramètres pour tous les champs autorisés.
‫Et donc cela créera essentiellement
‫un tableau contenant tous les arguments que nous avons transmis.
‫Donc, en gros, cela a été adopté après ce premier.
‫Donc, dans ce cas, il s'agit d'un tableau contenant le nom et l'e-mail.
‫Donc, ce que nous devons
‫faire maintenant, c'est essentiellement parcourir l'objet et pour chaque élément vérifier si
‫c'est l'un des champs autorisés, et
‫si c'est le cas, l'ajouter simplement à un nouvel objet, que
‫nous allons ensuite retourner à la fin .
‫Et il existe probablement de meilleures façons de
‫mettre cela en
‫œuvre, mais faisons-le très rapidement ici.
‫Nous allons donc
‫boucler l'objet en disant Objet. clés de l'objet dans lequel nous passons.
‫C'est donc l'un des moyens les plus simples de
‫parcourir un objet en JavaScript.
‫Donc, ici, cela renvoie essentiellement un tableau contenant tous
‫les noms de clés,
‫donc les noms de champ de cet
‫objet, puis nous pouvons les parcourir.
‫Ensuite, notre fonction de rappel.
‫Et pour chaque élément, c'est ce que nous allons faire.
‫Ainsi, si le tableau de champs autorisés inclut
‫l'élément actuel, donc le nom du champ actuel, nous souhaitons l'ajouter
‫à un nouvel objet.
‫Créons donc rapidement celui-ci ici,
‫donc const newObj qui est vide pour
‫l'instant, et au
‫final, c'est celui-là que nous allons retourner.
‫Donc newObj.
‫Donc, si le champ actuel est l'un des champs
‫autorisés, alors newObj avec le nom de champ du champ actuel doit être égal
‫à tout ce qui se trouve dans l'objet de l'élément
‫actuel, donc le nom du champ actuel.
‫Donc, si cela semble un peu déroutant,
‫il ne s'agit encore que de JavaScript standard,
‫cela n'a rien à voir avec aucun JS ou eXpress ou quelque
‫chose comme ça.
‫Encore une fois, tout ce que nous faisons ici est de
‫parcourir en boucle tous les champs qui se trouvent dans l'objet,
‫puis pour chaque champ, nous
‫vérifions s'il s'agit de l'un des champs autorisés.
‫Et si c'est le cas, alors nous créons un nouveau champ dans
‫le nouvel objet, bien
‫sûr avec le même nom, donc toujours name element, avec
‫exactement la même valeur que dans l'objet d'origine.
‫Et puis à la fin bien sûr, on renvoie celui-là.
‫Et donc tout cela devrait maintenant fonctionner ici.
‫Ensuite, tout ce que nous avons à faire
‫à la fin est d'envoyer cet utilisateur mis à jour au client.
‫Alors, utilisateur.
‫Maintenant, bien sûr, nous devons mettre le udatedUser ici, le
‫sauvegarder à nouveau, et maintenant cela devrait fonctionner.
‫Voir vraiment ce que nous avons fait ici était ..
‫mettre à jour l'utilisateur en dernier,
‫et avant cela, nous avons en fait filtré les noms de champs
‫indésirables qui ne sont pas autorisés à être mis à jour.
‫Alors essayons ça maintenant.
‫Et cet utilisateur ici est un utilisateur régulier, nous venons donc de
‫le créer, rappelez-vous
‫avec le nom de J.
‫Jetons donc un coup d'œil à Compass.
‫C'est donc un utilisateur normal, avec un nom de J.
‫Et donc mettons maintenant à
‫jour, puis nommons, et essayons également de mettre à jour le
‫rôle, ce qui encore une fois n'est pas autorisé.
‫Mais pour voir si notre code fonctionne, essayons-le.
‫Il y a donc déjà le nom, et disons que
‫nous sommes un
‫utilisateur malveillant essayant de changer notre rôle en admin.
‫Donc, tout est correct, je suppose,
‫alors envoyons-le maintenant, et
‫en effet voici notre objet mis à jour.
‫Nous obtenons donc notre nouveau nom, qui est Jonas Schmedtmann,
‫puis le rôle, qui est toujours utilisateur.
‫Il n'a pas mis à jour le rôle d'administrateur.
‫Parfait. C'est exactement ce que nous voulions.
‫Alors, sauvez ceci et revenons en arrière et en
‫fait, nous venons de terminer cette vidéo.
‫Ensuite, nous allons implémenter une fonctionnalité de
‫suppression de l'utilisateur actuel.
‫Nous avons donc travaillé sur la mise à jour. Ensuite, nous voulons permettre
‫à un utilisateur de se supprimer lui-même lorsqu'il ne veut
‫plus faire partie de notre application.