‫Narrateur : Jusqu'à présent, dans notre implémentation de
‫l'authentification, nous avons connecté les utilisateurs avec un mot de passe correct.
‫Donc, fondamentalement, nous avons terminé cette première étape du
‫flux de travail d'authentification
‫où un jeton Web JSON est créé
‫et renvoyé au client si l'utilisateur fournit une
‫adresse e-mail et un mot de passe corrects.
‫Ensuite, nous allons implémenter des routes protégées.
‫Donc, en gros, en utilisant le jeton Web
‫JSON créé afin de donner aux utilisateurs connectés l'accès aux routes protégées.
‫Et c'est la deuxième étape de l'authentification.
‫Et maintenant, allons de l'avant et implémentons cette fonctionnalité.
‫Disons donc que nous voulions protéger
‫la route getAllTours.
‫Donc, fondamentalement, autoriser uniquement les utilisateurs connectés
‫à accéder à une liste de toutes nos visites.
‫Et ce que cela signifie, c'est qu'avant d'exécuter
‫le gestionnaire get all tours, jetons
‫un coup d'œil à cela.
‫D'accord, donc avant d'exécuter ce descripteur ici, nous aurions
‫besoin d'avoir une vérification en place
‫afin de vérifier si l'utilisateur
‫est réellement connecté ou non, n'est-ce pas ?
‫Et donc la meilleure façon
‫de le faire, comme vous le savez
‫probablement déjà à ce stade, est d'utiliser une fonction middleware, d'accord ?
‫Donc, dans cette vidéo, afin
‫de protéger les routes, nous allons créer
‫une fonction middleware qui s'exécutera avant chacun de ces gestionnaires, d'accord.
‫Donc une fonction qui va s'asseoir ici,
‫donc avant que cette fonction ici puisse s'exécuter.
‫Et ce middleware renverra alors soit une
‫erreur si l'utilisateur n'est pas authentifié,
‫donc s'il n'est pas
‫connecté, soit il appellera le
‫middleware suivant qui est dans ce cas le gestionnaire getAllTours, non ?
‫Et cela protège efficacement cette route
‫contre les accès non autorisés.
‫Alors allons-y et créons rapidement
‫cette fonction middleware, puis
‫mettons-la ici
‫afin d'illustrer ce que je viens de dire.
‫D'accord, donc ici, dans notre contrôleur d'authentification, nous allons
‫à nouveau créer une nouvelle fonction
‫middleware et elle s'appelle protéger.
‫Très bien,
‫et comme avant, je vais utiliser catchAsync
‫car une fois de plus, toutes ces fonctions
‫sont en fait des fonctions asynchrone.
‫Très bien, et puis ici bien sûr, notre fonction
‫middleware et pour l'instant, appelons très simplement next
‫here juste pour que nous ayons en fait
‫n'importe quel corps ici dans
‫cette fonction middleware, puis revenons à nos
‫itinéraires de tournée et protégeons ensuite cet itinéraire, d'accord ?
‫Donc, tout d'abord, je dois réellement exiger ce
‫module de contrôleur d'authentification.
‫Donc
‫const et ensuite exiger que
‫ce soit dans les
‫contrôleurs, puis authController, d'accord.
‫Alors maintenant, connectons-le,
‫ici même dans l'itinéraire getAllTours.
‫D'accord.
‫Donc authController. protéger.
‫D'accord.
‫Et donc maintenant, cette fonction middleware va s'exécuter en
‫premier et encore, si l'utilisateur n'est pas authentifié, il y
‫aura une erreur.
‫Et bien sûr, le middleware suivant,
‫donc celui qui
‫reçoit et envoie toutes les tournées ne sera alors pas exécuté.
‫D'accord.
‫Et encore une fois, cela protégera efficacement l'accès à
‫cette ressource ici des utilisateurs qui ne sont pas connectés.
‫Très bien, alors revenons ici.
‫Pas les routes
‫utilisateur, mais le contrôleur d'authentification.
‫Très bien, et maintenant à propos de la mise en œuvre
‫de ce middleware de protection.
‫Que devrons-nous faire exactement ?
‫Eh bien, commençons par souligner quelques étapes ici.
‫D'accord, et en fait, nous devons tout d'abord marquer cette
‫fonction comme Async, sinon nous n'aurions pas vraiment besoin
‫de catchAsync, n'est-ce pas ?
‫Et vous verrez pourquoi nous avons besoin que ce soit une fonction
‫Async dans une seconde, d'accord ?
‫Mais maintenant, exposons en fait les étapes
‫que nous devons suivre pour implémenter ce middleware de protection.
‫Donc, comme avant, je vais
‫mettre ces étapes ici sous forme de commentaires.
‫Tout d'abord, nous devons obtenir le jeton.
‫Et
‫vérifiez s'il est là en
‫gros, donc vérifiez s'il existe.
‫Ensuite, nous devons valider le jeton.
‫Et donc c'est fondamentalement cette étape super
‫importante dont nous avons parlé précédemment où l'algorithme JWT vérifie si la signature est
‫valide ou si elle ne
‫l'est pas.
‫Et donc donc si le token est valide ou non, d'accord ?
‫Et en fait, appelons cela ici vérification.
‫Je pense que c'est comme ça que nous l'avons appelé dans cette
‫diapositive où nous en avons déjà parlé, d'accord.
‫Et si vous ne vous souvenez pas vraiment comment cela
‫a fonctionné, vous pouvez
‫toujours revenir en arrière et revoir cette conférence, d'accord ?
‫Ensuite, si la vérification a réussi, nous devons également vérifier
‫si l'utilisateur qui essaie d'accéder à la
‫route existe toujours, d'accord ?
‫Vérifiez donc si l'utilisateur existe toujours, et je vous expliquerai pourquoi
‫chacune de ces étapes est
‫nécessaire une fois que nous avons commencé à les implémenter, d'accord ?
‫Donc, pour l'instant, cela n'a peut-être pas beaucoup de sens pour
‫vous, mais encore une fois, je parlerai de chaque arrêt une fois que nous y serons.
‫D'accord?
‫Et enfin, nous devons également
‫vérifier
‫si l'utilisateur a changé
‫de mot de passe
‫après l'émission du JWT, d'accord ?
‫Eh bien, disons simplement jeton
‫ici, nous l'avons appelé jeton partout ailleurs, d'accord ?
‫Et donc seulement s'il n'y a eu aucun
‫problème dans aucune de ces étapes
‫ici, alors bien sûr, la prochaine sera appelée, ce qui aura
‫alors accès à la route que nous avons protégée.
‫Donc, dans notre exemple actuel, encore une fois, ce gestionnaire getAllTours.
‫Droit?
‫D'accord, mais revenons en arrière
‫et commençons à mettre en œuvre notre toute première étape ici.
‫Donc, en gros, obtenez
‫le jeton, puis vérifiez s'il existe réellement.
‫Une pratique courante consiste donc à envoyer un jeton à l'aide d'un en-tête http
‫avec la requête, d'accord ?
‫Voyons donc comment nous pouvons définir des en-têtes dans
‫Postman pour l'envoyer avec
‫la demande, puis comment nous pouvons
‫accéder à ces en-têtes dans Express.
‫Et commençons par celui-là en fait.
‫Alors ici dans apt. js Je pense que nous avons ce
‫middleware sympa ici, et donc ici, connectons-nous en fait à
‫la demande de la console. en-têtes, d'accord, nous
‫avons donc déjà parlé des en-têtes http, et
‫c'est ainsi que nous pouvons y accéder dans Express.
‫D'accord, donc essentiellement aux en-têtes de demande, donc
‫à ceux qu'un client peut envoyer avec sa demande.
‫D'accord, et donc ici dans Postman, passons maintenant à
‫la route que nous essayons de protéger.
‫Et puis ici, définissez un en-tête.
‫Et faisons un
‫test et définissons-le sur Jonas, d'accord ?
‫Maintenant, je vais juste
‫envoyer ceci et ici dans Express, jetons un coup d'œil à cela.
‫Et donc en effet ici, nous obtenons un objet avec tous les
‫en-têtes qui font partie de la requête.
‫Alors tout ça ici.
‫Et vous voyez qu'il y a un
‫tas d'en-têtes que Postman envoie en fait automatiquement
‫avec la demande, par exemple, il dit que l'agent utilisateur est
‫Postman, il envoie également l'hôte, et
‫d'autres dont nous parlerons plus tard comme
‫accepter par exemple.
‫Maintenant, ce qui compte ici, c'est en fait l'en-tête
‫que nous avons nous-mêmes défini.
‫D'accord, donc l'en-tête de test est défini sur jonas que nous
‫venons d'envoyer dans notre demande.
‫Maintenant, pour envoyer un jeton Web JSON en tant qu'en-tête, il existe en
‫fait une norme pour le faire.
‫Alors revenons ici, débarrassons-nous de tout cela.
‫Et donc cette norme pour l'envoi d'un jeton est que nous
‫devrions toujours utiliser un en-tête appelé autorisation.
‫D'accord?
‫Donc, juste comme ça, puis
‫la valeur de cet en-tête doit toujours commencer par
‫Bearer, d'accord ?
‫Car au fond on porte, on a, on possède ce jeton et puis
‫ici la valeur du jeton.
‫Donc, tout comme cette chaîne aléatoire que nous avons obtenue auparavant.
‫Laissons-la donc à ceci comme exemple, et
‫envoyons-la maintenant.
‫Et puis en effet, nous devrions l'obtenir ici.
‫D'accord.
‫Maintenant, Express transforme automatiquement tous les noms d'en-tête en minuscules,
‫comme vous pouvez le voir ici,
‫mais bien sûr, notre valeur d'en-tête ici est toujours la même.
‫D'accord, et donc fondamentalement, cette partie de la valeur d'en-tête
‫est notre jeton.
‫Et c'est ainsi que nous devrions
‫maintenant lire ce jeton à partir de l'en-tête.
‫D'accord?
‫Donc, s'il
‫y
‫a réellement req. en-têtes. autorisation, d'accord, et
‫si cela
‫commence essentiellement par cette chaîne de support ici, d'accord, alors
‫req. en-têtes. autorisation et maintenant
‫il s'agit d'une chaîne et
‫nous pouvons donc utiliser startWith sur
‫cela d'accord, donc c'est juste du JavaScript normal à
‫nouveau d'accord.
‫Et donc ce sont les conditions dans lesquelles nous voulons réellement
‫enregistrer un jeton, d'accord ?
‫Donc, encore une fois, au cas où
‫cet en-tête existe et que sa valeur commence par Bearer, d'accord.
‫Ensuite, dans ce cas, nous voulons dire que le jeton est égal
‫à req. en-têtes. autorisation et
‫maintenant comment obtenons-nous réellement cette deuxième partie
‫de la chaîne?
‫Eh bien, nous allons essentiellement diviser la chaîne
‫par ce caractère d'espace, d'accord, ce qui
‫créera ensuite un tableau avec
‫ce porteur
‫et avec ce jeton, puis nous
‫allons prendre cette partie du
‫tableau que nous voulons.
‫Alors divisez en utilisant l'espace, puis à
‫partir de ce tableau, nous voulons le deuxième élément.
‫D'accord?
‫Maintenant, nous ne pouvons pas réellement définir une variable à l'intérieur d'un
‫bloc if
‫parce que const et let, donc
‫la nouvelle déclaration de variable ES6 est en fait à
‫portée de bloc, et donc
‫tout ce que nous définissons dans ce bloc ici ne sera
‫alors pas disponible en dehors de celui-ci.
‫D'accord, et faisons ça à l'extérieur.
‫Et puis réaffectez simplement cette valeur au jeton.
‫D'accord.
‫Et maintenant, enregistrons le jeton sur la console juste
‫pour voir si cela fonctionne.
‫D'accord, et en fait, obtenons en quelque sorte un
‫vrai jeton ici.
‫Donc celui avec lequel nous venons de nous connecter.
‫Et puis mettez celui-là ici, d'accord.
‫Alors
‫envoyez-le, et ah!
‫Nous y voilà.
‫Nous avons donc ici nos données de jeton Web JSON que nous venons
‫d'envoyer avec la demande.
‫Désactivons rapidement ce journal de console ici.
‫Très bien, et juste avant de continuer,
‫vérifions si le jeton existe réellement.
‫D'accord.
‫Donc, s'il n'y a pas
‫de puits de jeton, alors, bien sûr, nous voulons créer une nouvelle erreur.
‫D'accord, et comme avant de
‫revenir de ce middleware et
‫d'appeler le suivant, d'accord.
‫Et maintenant, ici, nous allons ensuite créer une erreur et nous
‫passerons donc directement à
‫notre middleware global de gestion des erreurs avec cette erreur.
‫D'accord, donc si aucun jeton n'est envoyé avec la demande, cela signifie
‫que nous ne sommes pas connectés.
‫Envoyons donc à l'utilisateur auquel vous n'êtes pas
‫connecté.
‫Veuillez vous connecter pour y accéder.
‫Très bien, et maintenant le
‫code d'état pour ce genre de situation est
‫401, ce qui signifie non autorisé, d'accord ?
‫Je ne sais pas si nous l'avons déjà
‫utilisé et oui, en fait, nous l'avons fait ici aussi.
‫D'accord, et cela signifie essentiellement
‫que les données qui ont été envoyées dans la demande
‫sont correctes, mais elles ne sont pas suffisantes pour
‫que l'utilisateur accède à une ressource qu'il demande.
‫D'accord.
‫Sauvegardez-le ici
‫et testez-le à nouveau.
‫Donc, si nous supprimons essentiellement cet en-tête ici, nous
‫devrions immédiatement entrer dans cette erreur, n'est-ce
‫pas ?
‫Et en effet, vous n'êtes pas connecté, veuillez vous
‫connecter pour avoir accès.
‫Avec 401 non autorisé.
‫Super! Cette partie fonctionne donc déjà.
‫Très bien, et maintenant juste pour récapituler, donc
‫pour le moment nous n'envoyons aucun jeton avec la demande,
‫n'est-ce pas ?
‫Et donc pour cette raison, bien sûr, il n'y a pas de jeton, d'accord ?
‫Et par conséquent, nous créons
‫cette erreur, qui déclenchera ensuite notre middleware de gestion d'erreurs
‫pour renvoyer cette erreur au client, d'accord ?
‫Et puis bien sûr nous n'avons pas accès
‫à toutes les visites, car bien
‫sûr ce middleware s'exécute avant le contrôleur getAllTours.
‫Et donc maintenant, c'est vraiment protégé, d'accord ?
‫Cela fonctionne donc déjà très bien à ce stade.
‫Mais bien sûr, c'est loin d'être suffisant,
‫car il ne suffit pas d'envoyer un jeton avec une requête.
‫Il doit également être un jeton valide.
‫Donc, fondamentalement, un jeton où personne n'a
‫essayé de modifier la charge utile.
‫D'accord, et la charge utile, rappelez-vous, dans notre cas,
‫c'est toujours le user_id de l'utilisateur pour lequel le jeton a été émis.
‫Très bien, et nous devons
‫ensuite mettre en œuvre cette étape de vérification.
‫Mais cette conférence est déjà assez longue et il y
‫a encore beaucoup de choses à
‫faire ici, alors laissons cela pour la prochaine vidéo.