Maison >interface Web >js tutoriel >Maîtriser l'authentification sécurisée dans Node.js : connexion/déconnexion avec bcrypt.js et JWT
Imaginez que vous créez une application Web sur le point d'être lancée. Vous avez soigneusement conçu l'interface utilisateur, ajouté des fonctionnalités intéressantes et veillé à ce que tout se déroule sans problème. Mais à mesure que la date de lancement se rapproche, une préoccupation lancinante commence à vous inquiéter : la sécurité. Plus précisément, comment garantir que seuls les bons utilisateurs peuvent accéder aux bonnes parties de votre application. C'est là qu'intervient l'authentification.
L'authentification est le processus de vérification de l'identité d'un utilisateur, et c'est un aspect essentiel du développement Web. Dans le vaste paysage numérique, il est primordial de garantir que les utilisateurs peuvent se connecter et se déconnecter de votre application en toute sécurité. Un seul faux pas et votre application pourrait être vulnérable aux attaques, mettant en danger les données des utilisateurs.
Dans cet article, nous explorerons l'authentification sécurisée dans Node.js, en utilisant bcrypt.js pour hacher les mots de passe et les jetons JWT pour gérer les sessions utilisateur. À la fin, vous aurez une solide compréhension de la façon de mettre en œuvre un système de connexion/déconnexion solide, garantissant la sécurité des données de vos utilisateurs.
Alors, lançons-nous dans ce voyage pour construire un système d'authentification à toute épreuve, en commençant par la configuration de notre environnement jusqu'à la sécurisation de nos itinéraires avec JWT. Prêt à verrouiller votre application Node.js ? Commençons.
Tout d'abord, initialisez votre projet Node.js avec npm init -y, qui crée un fichier package.json avec les paramètres par défaut. Ensuite, installez les packages essentiels : express pour la configuration du serveur, mongoose pour la gestion de MongoDB, jsonwebtoken pour la gestion des jetons JWT, bcryptjs pour le hachage des mots de passe, dotenv pour les variables d'environnement, cors pour activer le partage de ressources entre origines croisées, cookie-parser pour analyser les cookies. Enfin, ajoutez nodemon comme dépendance de développement pour redémarrer automatiquement le serveur lorsque le code change.
1.`npm init -y` 2.`npm install express mongoose jsonwebtoken bcryptjs dotenv cors cookie-parser` 3.`npm install nodemon -D`
Modifiez maintenant le fichier package.json. Ajoutez des scripts comme mon code et tapez.
"scripts": { "dev": "nodemon backend/index.js", "start": "node backend/index.js" }, "type": "module",
Ensuite, nous allons configurer un serveur Express de base. Créez un fichier nommé index.js . Ce code initialise Express et crée une instance de l'application. Nous définirons ensuite une route pour l'URL racine ("/") afin de gérer les requêtes HTTP GET entrantes. Après cela, nous démarrerons le serveur sur le port 8000, lui permettant d'écouter les demandes entrantes.
import express from "express"; const app = express(); app.get("/", (req, res) => { res.send("Server is ready"); }); app.listen(8000, () => { console.log("Server is running on PORT 8000"); });
Maintenant, nous allons créer un dossier nommé « routes » et dans ce dossier, nous créerons un nouveau fichier nommé authRoute.js et collerons le code ci-dessous pour voir les bases des routes.
Dans cet extrait de code, nous configurons des routes pour différents points de terminaison d'authentification à l'aide d'Express. Tout d’abord, nous importons la bibliothèque express et créons une nouvelle instance de routeur. Ensuite, nous définissons trois routes GET : /signup, /login et /logout, chacune répondant par un objet JSON indiquant que le point de terminaison respectif a été atteint. Enfin, nous exportons l'instance de routeur comme exportation par défaut, la rendant disponible pour une utilisation dans d'autres parties de l'application.
1.`npm init -y` 2.`npm install express mongoose jsonwebtoken bcryptjs dotenv cors cookie-parser` 3.`npm install nodemon -D`
Modifiez maintenant le fichier index.js en ajoutant la route d'authentification pour tester vos points de terminaison.
"scripts": { "dev": "nodemon backend/index.js", "start": "node backend/index.js" }, "type": "module",
Maintenant, vous pouvez le tester dans votre navigateur... mais j'utiliserai Postman pour sa commodité. Vous pouvez tester tous les points finaux comme celui-ci.
De même, vous pouvez voir les autres itinéraires comme Déconnexion et Inscription.
Donc, notre application de base est prête... faites-en maintenant un système d'authentification robuste et approprié.
Maintenant, préparez d’abord notre base de données mongoDB. Pour ce faire, créez un dossier Model et en dessous un fichier User.js et dans ce fichier, ajoutez le schéma et le modèle Mongoose pour un utilisateur dans une base de données mongoDB. Le schéma comprend des champs pour le nom d'utilisateur, le nom complet, le mot de passe et l'e-mail, chacun avec des types de données spécifiés et des contraintes telles que l'unicité et le statut requis. Le champ du mot de passe comporte également une longueur minimale de 6 caractères.
import express from "express"; const app = express(); app.get("/", (req, res) => { res.send("Server is ready"); }); app.listen(8000, () => { console.log("Server is running on PORT 8000"); });
Connectons-nous maintenant à notre base de données. Nous allons créer un dossier nommé db et à l'intérieur, un fichier appelé connectDB.js. Dans ce fichier, nous allons définir une fonction asynchrone connectMongoDB qui tente de se connecter à une base de données MongoDB à l'aide de Mongoose. Il obtient la chaîne de connexion à la base de données à partir de la variable d'environnement MONGO_URI. Si la connexion réussit, il enregistre un message de réussite avec le nom d'hôte. En cas d'échec, il enregistre l'erreur et quitte le processus avec un code d'état de 1. La fonction est exportée pour être utilisée dans d'autres parties de l'application.
import express from "express"; // Create a new Express router instance const router = express.Router(); // Define a GET route for the signup endpoint router.get("/signup", (req, res) => { // Return a JSON response indicating that the signup endpoint was hit res.json({ data: "You hit signup endpoint", }); }); // Define a GET route for the login endpoint router.get("/login", (req, res) => { // Return a JSON response indicating that the login endpoint was hit res.json({ data: "You hit login endpoint", }); }); // Define a GET route for the logout endpoint router.get("/logout", (req, res) => { // Return a JSON response indicating that the logout endpoint was hit res.json({ data: "You hit logout endpoint", }); }); // Export the router instance as the default export export default router;
Maintenant, pour utiliser MONGO_URI, nous devons le créer dans un fichier .env. Ici, j'ai utilisé la chaîne de connexion de configuration mongoDB locale. Si vous le souhaitez, vous pouvez également utiliser l'atlas mongoDB.
import express from "express"; import authRoute from "./routes/authRoutes.js"; const app = express(); app.get("/", (req, res) => { res.send("Server is ready"); }); app.use("/api/auth", authRoute); app.listen(8000, () => { console.log("Server is running on PORT 8000"); });
Faites maintenant la fonction d'inscription. Pour ce 1er, créez un contrôleur de dossier et déposez-y le fichier authController.js
import mongoose from "mongoose"; // Define the User schema with various fields and their data types const userSchema = new mongoose.Schema( { // The unique username of the user username: { type: String, required: true, unique: true, }, fullName: { type: String, required: true, }, // The password of the user (min length: 6) password: { type: String, required: true, minLength: 6, }, // The email of the user (unique) email: { type: String, required: true, unique: true, }, }, { timestamps: true } ); // Create the User model based on the userSchema const User = mongoose.model("User", userSchema); // Export the User model export default User;
Tout d’abord, il extrait le nom complet, le nom d’utilisateur, l’e-mail et le mot de passe du corps de la demande. Il valide le format de l'e-mail à l'aide d'une expression régulière, renvoyant un statut 400 si le format n'est pas valide.
Ensuite, la fonction vérifie si le nom d'utilisateur ou l'e-mail existe déjà dans la base de données. Si l'une ou l'autre est prise, un statut 400 avec un message d'erreur est renvoyé. Il garantit également que le mot de passe comporte au moins 6 caractères, envoyant 400 statuts supplémentaires si cette condition n'est pas remplie.
Le mot de passe est ensuite haché de manière sécurisée à l'aide de bcrypt. Une nouvelle instance utilisateur est créée avec les données fournies et enregistrée dans la base de données.
Après l'enregistrement, la fonction génère un jeton JWT, le définit comme cookie et renvoie un statut 201 avec l'ID de l'utilisateur, son nom complet, son nom d'utilisateur et son e-mail. Si des erreurs se produisent, elles sont enregistrées et un statut 500 est envoyé avec un message « Erreur interne du serveur ».
Pour rendre cette fonction active vous devez les importer
1.`npm init -y` 2.`npm install express mongoose jsonwebtoken bcryptjs dotenv cors cookie-parser` 3.`npm install nodemon -D`
Vous avez remarqué quelque chose ? une nouvelle chose appelée generateTokenAndSetCookie... permet de voir son code... créez un dossier utils et là generateTokenAndSetCookie.js.
"scripts": { "dev": "nodemon backend/index.js", "start": "node backend/index.js" }, "type": "module",
La fonction **generateTokenAndSetCookie ** crée un JWT et le stocke dans un cookie pour l'authentification de l'utilisateur.
Génération JWT :
La fonction utilise la bibliothèque jsonwebtoken pour créer un JWT. Il signe le jeton avec l'ID de l'utilisateur et une clé secrète (JWT_SECRET à partir des variables d'environnement), le faisant expirer dans 15 jours.
Paramétrage du cookie :
Le token est ensuite stocké dans un cookie sur le navigateur de l'utilisateur. Le cookie est configuré avec plusieurs attributs de sécurité :
Cette fonction garantit donc que la session de l'utilisateur est à la fois sécurisée et persistante, ce qui en fait un élément crucial du processus d'authentification.
Ici, nous devons ajouter une autre variable d'environnement JWT_SECRET dans .env. Vous pouvez ajouter n'importe quel type de mélange de nombre et de chaîne comme celui-ci.
import express from "express"; const app = express(); app.get("/", (req, res) => { res.send("Server is ready"); }); app.listen(8000, () => { console.log("Server is running on PORT 8000"); });
Maintenant, notre fonction d'inscription est terminée... alors faites son itinéraire maintenant.
import express from "express"; // Create a new Express router instance const router = express.Router(); // Define a GET route for the signup endpoint router.get("/signup", (req, res) => { // Return a JSON response indicating that the signup endpoint was hit res.json({ data: "You hit signup endpoint", }); }); // Define a GET route for the login endpoint router.get("/login", (req, res) => { // Return a JSON response indicating that the login endpoint was hit res.json({ data: "You hit login endpoint", }); }); // Define a GET route for the logout endpoint router.get("/logout", (req, res) => { // Return a JSON response indicating that the logout endpoint was hit res.json({ data: "You hit logout endpoint", }); }); // Export the router instance as the default export export default router;
ok, modifions maintenant notre index.js Ici, nous avons ajouté quelques nouvelles importations. dotenv : Charge les variables d'environnement en toute sécurité à partir de .env ; express.json() : Analyse les requêtes JSON entrantes ; express.urlencoded({ extended: true }): Analyse les données codées en URL ; cookieParser : Gère les cookies pour les jetons JWT ; connectMongoDB() : Se connecte à MongoDB pour le stockage des données ; Routes : /api/auth gère l'inscription, la connexion et la déconnexion.
Voici le code mis à jour d'index.js
1.`npm init -y` 2.`npm install express mongoose jsonwebtoken bcryptjs dotenv cors cookie-parser` 3.`npm install nodemon -D`
Alors. il est maintenant temps de tester notre fonction d'inscription dans Postman. Voyons si ça marche ou pas.
Voici donc les résultats.
Ici, vous pouvez voir qu'il fonctionne correctement et vous pouvez également le vérifier dans votre base de données mongoDB.
Faites maintenant la fonction de connexion. Revenons à notre fichier authController.js
"scripts": { "dev": "nodemon backend/index.js", "start": "node backend/index.js" }, "type": "module",
Le contrôleur de connexion authentifie un utilisateur en vérifiant son nom d'utilisateur et son mot de passe. Il recherche d'abord l'utilisateur dans la base de données en utilisant le nom d'utilisateur. S'il est trouvé, il compare le mot de passe fourni avec le mot de passe haché stocké dans la base de données à l'aide de bcrypt. Si le nom d'utilisateur ou le mot de passe est incorrect, il renvoie une réponse d'erreur. En cas de vérification réussie, il génère un jeton JWT, le définit comme cookie à l'aide de generateTokenAndSetCookie et répond par un message de réussite, indiquant que l'utilisateur est connecté avec succès.
Ajoutons notre itinéraire de connexion dans authRoutes.js
import express from "express"; const app = express(); app.get("/", (req, res) => { res.send("Server is ready"); }); app.listen(8000, () => { console.log("Server is running on PORT 8000"); });
Testons-le dans Postman.
Ici, vous pouvez voir qu'il s'affiche avec succès Connecté.
D'accord. Maintenant, la dernière fonction, c'est-à-dire la fonction de déconnexion. Mettons en œuvre cela. C'est assez simple.
import express from "express"; // Create a new Express router instance const router = express.Router(); // Define a GET route for the signup endpoint router.get("/signup", (req, res) => { // Return a JSON response indicating that the signup endpoint was hit res.json({ data: "You hit signup endpoint", }); }); // Define a GET route for the login endpoint router.get("/login", (req, res) => { // Return a JSON response indicating that the login endpoint was hit res.json({ data: "You hit login endpoint", }); }); // Define a GET route for the logout endpoint router.get("/logout", (req, res) => { // Return a JSON response indicating that the logout endpoint was hit res.json({ data: "You hit logout endpoint", }); }); // Export the router instance as the default export export default router;
Le contrôleur de déconnexion déconnecte en toute sécurité un utilisateur en effaçant le cookie JWT du navigateur du client à l'aide de res.cookie, en définissant sa valeur sur une chaîne vide et son maxAge sur 0, garantissant ainsi une expiration immédiate. Une fois la suppression réussie des cookies, il envoie une réponse réussie avec un message indiquant que l'utilisateur est déconnecté avec succès. Si une erreur se produit au cours de ce processus, il détecte l'erreur, l'enregistre et renvoie une réponse d'erreur interne du serveur.
Ajoutez cet itinéraire à notre authRoute.js
import express from "express"; import authRoute from "./routes/authRoutes.js"; const app = express(); app.get("/", (req, res) => { res.send("Server is ready"); }); app.use("/api/auth", authRoute); app.listen(8000, () => { console.log("Server is running on PORT 8000"); });
d'accord. Testons notre dernière fonctionnalité, si elle fonctionne bien ou non.
Oh !…Ça marche très bien. ??
Donc, notre backend complet de cette authentification est maintenant prêt. ??
Si vous ne voulez pas tout coder vous-même et souhaitez une solution rapide, j'ai créé un package npm appelé auth0_package. Vous pouvez l'obtenir à partir d'ici.
Vous pouvez obtenir mon code ci-dessus ici dans ce dépôt github ici.
Maintenant, votre application backend est terminée. Dans le prochain blog, j'expliquerai comment intégrer cela à votre frontend. Alors restez à l'écoute pour ça ??.
En conclusion, la mise en œuvre d'une authentification sécurisée dans une application Node.js est cruciale pour protéger les données des utilisateurs et garantir que seuls les utilisateurs autorisés peuvent accéder à des parties spécifiques de votre application. En utilisant bcrypt.js pour le hachage de mot de passe et les jetons JWT pour la gestion de session, vous pouvez créer un système de connexion/déconnexion robuste. Cette approche améliore non seulement la sécurité, mais offre également une expérience utilisateur transparente. La configuration d'une base de données MongoDB et l'utilisation d'Express pour le routage renforcent encore l'infrastructure backend. Grâce à ces outils et techniques, vous pouvez lancer votre application Web en toute confiance, sachant qu'elle est bien protégée contre les accès non autorisés et les menaces de sécurité potentielles.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!