‫Instructeur : Dans cette
‫conférence, nous allons donc gérer les mots de passe de nos utilisateurs dans la base de données.
‫Et par là, j'entends d'abord valider si
‫le mot de passe saisi est égal au mot de passe confirmé, puis
‫également crypter le mot de passe dans la base de données afin
‫de le protéger contre les attaques.
‫Et donc la première chose que
‫nous allons faire est de valider si les deux mots de passe saisis sont les mêmes.
‫Et le meilleur endroit pour le faire
‫est ici dans le mot de passe de confirmation, d'accord ?
‫Et donc écrivons notre validateur personnalisé pour ça, d'accord ?
‫Alors rappelez-vous, nous utilisons la propriété validate et ensuite,
‫puisque nous voulons créer une
‫fonction et également un message d'erreur, ouvrons un nouvel objet
‫ici et puis créons un validateur,
‫qui sera la fonction
‫et commençons en fait par celui-ci.
‫Alors, rappelez-vous, tout ce dont nous avons besoin ici
‫est de spécifier une simple fonction de rappel qui sera ensuite appelée
‫lors de la création du nouveau document.
‫Donc, fonction, et
‫là encore, nous ne pouvons pas utiliser de fonction flèche
‫car nous devons en fait utiliser le mot-clé disk.
‫D'accord?
‫Alors, rappelez-vous qu'à partir de la fonction de validation,
‫nous retournons soit vrai soit faux
‫et si la valeur de retour est fausse,
‫cela signifie que nous allons obtenir une erreur de validation, d'accord ?
‫Et, bien sûr, si c'est vrai, alors non.
‫Et donc ce que nous voulons ici, c'est dire que l'élément courant donc, mot
‫de passe confirmé, est égal à ce mot de passe point, donc, mot
‫de passe confirmé, est égal à ce mot de passe
‫point, et c'est tout !
‫Ainsi, par exemple, si la confirmation du mot de passe est A-B-C
‫et que le mot de passe est également
‫A-B-C, cela retournera bien sûr vrai, d'accord ?
‫Et alors la validation est
‫passée et aucune erreur ne se produira.
‫Mais, si le mot de passe initial est, disons, X-Y-Z, alors
‫bien sûr, cela va retourner faux
‫et nous aurons une erreur de validation, d'accord ?
‫Donc, très simple, mais nous devons garder à
‫l'esprit que cela ne fonctionnera que sur la sauvegarde, d'accord ?
‫J'en ai donc déjà parlé
‫lorsque nous avons utilisé le validateur personnalisé sur le modèle de tournée, n'est-ce pas ?
‫Mais je vous le rappelle
‫ici encore parce que c'est absolument crucial ici à ce stade, d'accord ?
‫Alors laissez-moi l'écrire ici pour vous.
‫(clavier
‫en cliquant)
‫Lors de l'enregistrement.
‫D'accord?
‫Et pour cette raison, chaque fois que nous voulons mettre à
‫jour un utilisateur, nous devrons toujours utiliser la sauvegarde et
‫non, par exemple, en trouver un et mettre à jour comme
‫nous l'avons fait avec nos visites, d'accord ?
‫Alors gardons cela à l'esprit lorsque nous
‫écrivons le reste du code dans le reste de la section
‫et en particulier pour la mise à jour, d'accord ?
‫Car disons que nous avons mis à jour le mot de passe de
‫l'utilisateur simplement avec une mise à jour régulière.
‫Alors dans ce cas, ce mot de passe de confirmation
‫de validation que nous avons ici ne fonctionnerait plus, d'accord ?
‫Et bien sûr, cela ne peut pas arriver, d'accord ?
‫Et donc, encore une fois, gardez à l'esprit que cela ne fonctionnera
‫que lorsque nous créerons un nouvel objet, ainsi de suite dot create, ou on save.
‫D'accord?
‫Alors, sur créer et
‫enregistrer, Alors, sur créer et enregistrer, d'accord
‫?
‫Nous créons donc un nouvel objet en utilisant create, n'est-ce pas ?
‫Donc, ici, j'ai utilisé un dot create Donc, ici,
‫j'ai utilisé un dot create,
‫mais rappelez-vous comment je
‫vous ai également montré que nous pouvons utiliser un utilisateur
‫dot save, comme ça, n'est-ce pas ?
‫Et en fait, nous pouvons également utiliser un utilisateur dot
‫save afin de mettre à jour l'utilisateur, d'accord ?
‫Mais encore une fois, plus à ce sujet un peu plus tard.
‫D'accord?
‫Essayons maintenant cette validation ici, d'accord ?
‫Alors tout d'abord, essayons simplement de créer
‫un nouvel utilisateur avec ces données
‫ici, ce qui ne devrait pas fonctionner car nous
‫avons déjà un utilisateur avec cette adresse e-mail et nous avons dit
‫que celui-ci devrait être unique et donc ne
‫devrait pas fonctionner.
‫D'accord, et bien sûr notre erreur de clé en double, n'est-ce pas ?
‫Maintenant, si vous étiez en production,
‫alors bien sûr, nous obtiendrions déjà notre erreur joliment formatée que
‫nous avons créée dans la dernière section, n'est-ce pas ?
‫Mais en ce moment nous sommes en développement et c'est donc l'erreur que nous avons
‫définie que nous voulons voir.
‫D'accord?
‫Utilisons donc simplement un autre e-mail ici
‫et puisque nous travaillons sur l'e-mail
‫ici, voyons également comment fonctionne la validation de l'adresse e-mail.
‫Disons donc que nous l'avons spécifié comme notre e-mail.
‫Et donc, nous voyons l'erreur, "veuillez fournir un e-mail valide. " D'accord?
‫Alors testons-le juste comme ça car je pense que cela ne
‫devrait pas non plus être valide.
‫C'est peut-être le cas, mais voyons voir.
‫Et oui, en fait ce n'est pas
‫parce qu'il n'y a pas de noms de domaine avec une seule lettre, d'accord ?
‫Et donc ce validateur est assez spécifique
‫donc c'est vraiment bien.
‫Maintenant, si nous le faisons comme ça, alors bien sûr, cela devrait fonctionner.
‫Mais de toute façon, ce que nous
‫voulions tester ici, ce sont ces différents mots de passe, d'accord ?
‫Et je me souviens maintenant
‫que nous n'avons pas créé de message d'erreur, je crois.
‫Et oui, nous ne l'avons pas fait.
‫Et donc, ajoutons cela ici aussi.
‫Donc message, ne
‫sont pas les
‫mêmes.
‫D'accord.
‫Ajoutons donc quelque chose ici, peu importe.
‫Et maintenant, les mots de passe ne sont pas les mêmes, d'accord ?
‫Tellement parfait.
‫Et maintenant bien sûr notre validation devrait être passée.
‫Et effectivement, c'est le cas et nous avons créé notre nouvel utilisateur.
‫Passons à Compass ici, jetons
‫un coup d'œil, puis supprimez-le afin que
‫je puisse plus tard créer plus d'utilisateurs avec le même e-mail.
‫D'accord?
‫Et de toute façon, nous ne voulons pas de
‫tous ces déchets ici, donc tous ces utilisateurs de test, d'accord ?
‫Mais maintenant, la prochaine étape consiste à crypter ces mots
‫de passe simples que nous stockons actuellement
‫dans notre base de données.
‫Donc, comme je l'ai mentionné dans la dernière
‫vidéo, lorsque nous travaillons avec l'authentification,
‫l'un des principes les plus fondamentaux est
‫de ne jamais stocker de mots de passe simples dans une base de données, d'accord ?
‫C'est donc quelque chose qui n'est absolument pas acceptable, d'accord ?
‫Nous devrions donc toujours crypter les mots de passe des utilisateurs car
‫imaginez que pour une raison quelconque,
‫un pirate informatique accède à la base de données.
‫Si les mots de passe y sont stockés en clair, alors il
‫peut simplement se connecter en tant qu'utilisateur, puis
‫faire ce qu'il veut vraiment et
‫causer beaucoup de dégâts dans certains cas, d'accord ?
‫Et donc nous devons absolument empêcher cela.
‫Et donc allons de l'avant et mettons cela en œuvre.
‫Maintenant, quel est le meilleur endroit pour le faire ?
‫Eh bien, je dirais que le modèle est toujours le meilleur
‫endroit pour faire ce genre de fonctionnalité.
‫Donc dans ce cas, le chiffrement parce
‫qu'il a vraiment à voir avec les données elles-mêmes et
‫donc il devrait être sur
‫le modèle et non dans le contrôleur, d'accord ?
‫Donc, encore une fois, gardez à l'esprit la philosophie des gros
‫modèles et des contrôleurs minces ici.
‫D'accord?
‫Alors, comment allons-nous maintenant implémenter ce cryptage ?
‫Eh bien, c'est un autre cas d'utilisation
‫parfait pour utiliser le middleware Mongoose.
‫Et celui que nous
‫allons utiliser est un middleware de pré-sauvegarde.
‫Donc, en gros, documentez le middleware, d'accord ?
‫Alors, rappelez-vous que nous avons défini cela sur le schéma, d'accord ?
‫Et dans ce cas, nous voulons définir
‫un pré-crochet, donc un pré-middleware à l'enregistrement, d'accord ?
‫donc un pré-middleware à l'enregistrement, d'accord ?
‫Et la raison pour laquelle nous le
‫faisons comme ça est
‫que la fonction middleware que nous allons spécifier ici, donc
‫le cryptage, va alors se produire entre le
‫moment où nous recevons ces données et le
‫moment où elles sont réellement persistées jusqu'au base de données, d'accord ?
‫C'est donc là que s'exécute le middleware de pré-enregistrement.
‫Entre l'obtention des données et leur enregistrement dans la base de données.
‫Et c'est donc le moment idéal pour manipuler les données.
‫D'accord?
‫Donc,
‫une fonction, et puis rappelons-nous que nous avons accès
‫à la fonction suivante afin d'appeler le prochain middleware.
‫D'accord, maintenant nous ne voulons crypter le mot de passe que
‫si le champ du mot de passe a été mis à jour, d'accord ?
‫Donc, en gros, seulement lorsque le mot de passe est vraiment modifié
‫ou également lorsqu'il est créé, d'accord ?
‫Parce qu'imaginez que l'utilisateur ne fait que mettre à jour l'e-mail.
‫Alors dans ce cas, bien
‫sûr, nous ne voulons pas crypter à nouveau le mot de passe, n'est-ce pas ?
‫Et donc nous pouvons le faire avec Mongoose.
‫Et donc nous allons dire, si et ensuite ceci, qui fait
‫référence au document actuel, n'est-ce pas ?
‫Et donc dans ce cas, à l'utilisateur
‫courant puis est modifié.
‫D'accord?
‫Nous avons donc une méthode sur tous les documents que nous
‫pouvons utiliser si un certain champ a été modifié.
‫Et donc ici, il faut passer le nom du champ, donc
‫"mot de passe. " D'accord?
‫Et donc fondamentalement, ce que nous voulons
‫faire ici, c'est dire que si le mot de passe n'a
‫pas été modifié, alors non, alors dans ce cas, revenons
‫simplement de cette fonction et n'exécutons aucun des autres
‫codes qui se trouvent ici, puis
‫appelons le prochain middleware.
‫D'accord?
‫Encore une fois, si le mot de passe n'a pas été
‫modifié, sortons simplement de cette
‫fonction et appelons le middleware suivant.
‫Sinon, nous exécuterons ensuite le code
‫que je vais mettre ici.
‫Et maintenant, il est enfin temps de crypter,
‫ou comme on peut aussi dire, de hacher le mot de passe, d'accord ?
‫Vous verrez donc le terme « hachage » ou « hachage
‫» tout le temps et cela signifie donc également le cryptage, d’accord ?
‫Maintenant, nous allons faire ce cryptage, ou
‫hachage, en utilisant un algorithme de
‫hachage très connu, bien étudié et très populaire appelé bcrypt.
‫D'accord?
‫Donc, cet algorithme va d'abord saler puis hacher notre mot de passe
‫afin de le rendre vraiment fort pour le protéger
‫contre les attaques par force brute, d'accord ?
‫Et c'est donc toute la
‫raison pour laquelle le cryptage doit être vraiment fort.
‫Parce que les attaques par force brute pourraient essayer
‫de deviner certains mots de passe s'ils ne sont pas vraiment cryptés.
‫Et rappelez-vous comment j'ai dit que bcrypt va saler notre mot de passe
‫et cela signifie simplement qu'il va ajouter une chaîne aléatoire
‫au mot de passe afin que deux mots de passe égaux
‫ne génèrent pas le même hachage, d'accord ?
‫Avoir du sens ?
‫Maintenant, je ne vais pas entrer dans tous les détails cryptographiques sur
‫la façon dont cela fonctionne vraiment dans les coulisses
‫et pourquoi nous avons besoin d'un système aussi complexe, d'accord ?
‫Mais bien sûr, vous pouvez lire tout ce que vous voulez sur bcrypt en ligne.
‫Il y a vraiment une tonne de choses
‫intéressantes à découvrir là-bas, d'accord ?
‫Quoi qu'il en soit, allons maintenant de l'avant et utilisons le
‫package bcrypt js afin d'utiliser cet algorithme.
‫Donc, donc
‫npm install
‫donc npm install
‫bcryptjs.
‫D'accord?
‫Et donc, il s'agit essentiellement d'une implémentation
‫bcrypt pour Javascript.
‫D'accord?
‫Revenons à notre terminal principal,
‫puis importons-le ici.
‫Et celui-ci s'appelle par défaut uniquement bcrypt, d'accord ?
‫Et pas bcryptjs.
‫(clavier cliquable) D'accord.
‫D'accord.
‫Et maintenant, utilisons-le réellement.
‫Donc, nous voulons dire que ce mot de passe dot, donc
‫le mot de passe actuel dans ce
‫document doit être égal à bcrypt dot hash doit
‫être égal à bcrypt dot hash puis à notre
‫mot de passe actuel.
‫D'accord?
‫Et puis ici, nous devons spécifier un paramètre de coût, d'accord ?
‫Et nous pourrions en fait le faire de deux manières.
‫Donc, la première façon sera de générer manuellement le sel, de
‫sorte que cette chaîne aléatoire en gros,
‫qui sera ajoutée à notre
‫mot de passe, puis utilisera ce sel ici dans cette fonction de hachage.
‫D'accord?
‫Mais à la place, pour le rendre
‫un peu plus facile, nous pouvons aussi simplement passer ici un paramètre
‫de coût dans cette fonction.
‫Et c'est donc essentiellement une
‫mesure de l'intensité du processeur de cette opération, d'accord ?
‫Et la valeur par défaut ici, je crois, est de 10,
‫mais pour le moment, c'est un peu mieux d'utiliser 12 parce
‫que les ordinateurs sont devenus de plus en plus puissants.
‫Donc, comme il y a 20 ans, vous auriez pu en
‫utiliser huit ici, puis un peu plus
‫tard que 10, mais à l'heure actuelle, il est préférable d'en utiliser 12.
‫Et donc plus ce coût
‫est élevé ici, plus le processus sera gourmand en
‫CPU et mieux le mot de passe sera crypté, d'accord ?
‫Et bien sûr, nous pourrions aller encore
‫plus haut, mais cela prendrait beaucoup trop de temps, d'accord ?
‫Et je vais vous le montrer dans une seconde.
‫D'accord?
‫Mais pour l'instant, terminons
‫en fait ceci car il reste une chose ici.
‫Donc, ce hachage ici est en fait la version asynchrone,
‫mais il existe également une version synchrone.
‫Mais comme vous le savez déjà, nous ne
‫voulons pas utiliser
‫la version synchrone car cela bloquera la boucle d'événement et empêchera
‫ensuite les autres utilisateurs d'utiliser l'application.
‫Donc, tout comme nous l'avons appris au début.
‫Et donc bien sûr nous
‫souhaitons utiliser la version asynchrone qui est celle-ci.
‫Et cela renverra alors une
‫promesse et cette promesse, bien sûr, nous devons l'attendre.
‫Et donc, nous devons utiliser wait, puis dire que cette
‫fonction est une fonction asynchrone, comme celle-ci.
‫Alors, récapitulons cela ici.
‫Donc, nous voulons définir notre mot de passe actuel
‫essentiellement pour crypter cette version du mot de passe d'origine avec un coût de 12, pour
‫ne pas le rendre trop facile à casser
‫le mot de passe, mais aussi pour ne pas faire en sorte que
‫l'application prenne trop de temps pour crypter le mot de passe, d'accord?
‫Donc, avec cela, nous avons chiffré notre mot de passe
‫et maintenant à la fin, ce que
‫nous devons faire, c'est essentiellement supprimer le mot de passe de confirmation, d'accord ?
‫Parce qu'à ce stade, nous n'avons
‫que le vrai mot de passe haché, n'est-ce pas ?
‫Donc, cette confirmation de mot de passe
‫à points, donc, cette
‫confirmation de mot de passe à points, et comment
‫nous supprimons fondamentalement le champ, donc ne pas persister dans la
‫base de données consiste à le définir sur non défini.
‫D'accord?
‫Donc, nous n'avons vraiment besoin de ce mot de passe confirmé ici
‫que pour la validation que nous avons implémentée auparavant.
‫Donc, juste pour s'assurer que
‫l'utilisateur a bien entré deux mots de passe
‫égaux afin qu'il ne fasse aucune erreur avec son mot de passe.
‫Droit?
‫Et donc une fois cette validation réussie,
‫nous n'avons plus besoin de ce champ donc nous
‫ne voulons vraiment pas le persister dans la base de données.
‫Et c'est pourquoi nous l'avons simplement défini ici sur undefined.
‫D'accord?
‫Maintenant, vous vous demandez peut-être pourquoi cela fonctionne, car
‫nous avons en fait défini la confirmation du mot de passe
‫sur une valeur requise, n'est-ce pas ?
‫Mais cela signifie simplement qu'il s'agit d'une entrée requise,
‫et non qu'elle doit être conservée dans la base
‫de données, d'accord ?
‫à la base de données, d'accord ?
‫Maintenant, juste pour terminer, nous devons bien sûr également appeler ensuite.
‫D'accord?
‫Faisons une sauvegarde.
‫Et en fait, je vais ajouter quelques commentaires
‫ici pour que ce soit vraiment clair pour vous.
‫Donc, fondamentalement, ce que cela fait, c'est de n'exécuter cette
‫fonction que
‫si le mot
‫de passe a été réellement modifié.
‫Ensuite, ici,
‫hachez le mot de passe avec un coût de 12.
‫Et puis, supprimez
‫le champ de confirmation du mot de passe.
‫D'accord.
‫Et maintenant, allons-y et testons cela.
‫Et je vais maintenant créer un nouvel utilisateur avec exactement ces
‫données et jetons maintenant un œil au résultat.
‫Et en effet, nous obtenons maintenant ce mot de passe très
‫étrange qui est en fait la version cryptée de pass1234.
‫Et aussi, comme vous le voyez, la confirmation du mot de passe n'est plus là.
‫D'accord?
‫Et donc juste comme ça, nous avons maintenant stocké les
‫utilisateurs de manière sécurisée dans notre base de données.
‫Permettez-moi maintenant de vous montrer comment cela fonctionnera si,
‫par exemple, nous le réglons sur 16 ici.
‫Et je dois changer l'email ici.
‫Et donc cela devrait maintenant prendre beaucoup de temps et je ne suis
‫même pas sûr de pouvoir attendre.
‫Oh, en fait, cela a pris environ quatre secondes et demie.
‫Mais c'est encore un peu trop je crois, d'accord ?
‫Alors, replaçons-le sur
‫12 et
‫ça devrait être mieux, d'accord ?
‫Et maintenant, supprimons encore une
‫fois ces utilisateurs que nous venons de créer.
‫Et en fait, je dois me débarrasser
‫de ce premier car celui-ci a toujours le mot de passe en clair.
‫Et donc cet utilisateur ne fonctionnera
‫pas lorsque nous commencerons à connecter les utilisateurs
‫en fonction de leur mot de passe.
‫D'accord?
‫Alors débarrassons-nous de cela.
‫D'accord?
‫Et aussi ce que je voulais vous montrer
‫ici, c'est que nous avons mis exactement le même mot de
‫passe pour ces deux utilisateurs que nous avons créés, n'est-ce pas ?
‫Mais vous voyez que le mot
‫de passe crypté est en fait très différent, non ?
‫Et c'est donc le pouvoir de saler le mot de
‫passe avant de le hacher.
‫D'accord?
‫Alors juste comme ça, nous avons, encore une fois, mis en place une gestion des
‫mots de passe très sécurisée et bonne.