Passport es muy fácil de integrar en el paquete NodeJs, que se utiliza para agregar funciones de autenticación a nuestro sitio web o aplicación web.
Para mostrar el uso de Passport en Nodejs, comenzamos con la creación de una aplicación Node muy simple.
Crear una aplicación de Node simple usando express:
Paso 1: cree una nueva carpeta (he llamado a la carpeta «NODEAPP») y cree un nuevo archivo llamado «Server.js» dentro de ella.
Paso 2: Inicializar npm usando el comando «npm init -y». El archivo Package.json se agregará a la carpeta de su proyecto.
npm init-y
Paso 3: instale todos los paquetes necesarios, es decir, express , body-parser (se usará para obtener datos de formularios HTML más adelante), mongoose (se usa para conectarse a nuestra base de datos MongoDB), usando el comando:
npm install express body-parser mongoose
1 archivo, llamado » package-lock.json » se agregará a la estructura de su proyecto, y 1 carpeta llamada » node_modules » se agregará a la estructura de su proyecto después de ejecutar el comando anterior.
Estructura del proyecto: la estructura final del proyecto debería verse así:
Paso 4: Agregar código básico a nuestro archivo Server.js .
Server.js
// Telling node to include the following // external modules var express = require('express'); var app = express(); // Mongoose for connecting to our database const mongoose = require("mongoose"); // Body parser to fetch HTML form data later on const bodyParser = require("body-parser"); // Connecting mongoose to our database // named "userDatabase" mongoose.connect( 'mongodb://localhost:27017/userDatabase', { useNewUrlParser: true, useUnifiedTopology: true }); // Handling get request on home route. app.get("/", function (req, res) { res.send("This is the home route"); }); // Allowing app to listen on port 3000 app.listen(3000, function () { console.log("server started successfully"); })
Paso 5: también puede verificar abriendo el navegador y escribiendo http://localhost:3000 . Debería ver una página en blanco con la siguiente respuesta.
Paso 6: Agregar autenticación a nuestro sitio web. Una forma sencilla de agregar una función de autenticación a nuestro sitio web es tomar el correo electrónico y la contraseña ingresados por el usuario y guardarlos directamente en la base de datos. De manera similar, cuando el usuario quiera iniciar sesión, solicite su correo electrónico y contraseña, y si algún registro coincide con el correo electrónico y la contraseña ingresados, entonces el usuario es auténtico y el inicio de sesión es exitoso.
Server.js
/*We are going to add simple authentication to our website We are going to collect data(email and password) entered by user in the HTML form, created in the INDEX.HTML file, and we are going to store that data in our database this is how we can simply register any new user */ /* if we want to log in our already registered user, then we collect email and password from HTML form created in LOGIN.HTML file, and we can find data(if any) associated with this email, and return it to user */ var express = require('express'); var app = express(); const bodyParser = require("body-parser"); // Allowing app to use body parser app.use(bodyParser.urlencoded({extended:true})); // Connecting mongoose to our database // named "userDatabase" mongoose.connect( 'mongodb://localhost:27017/userDatabase' { useNewUrlParser: true, useUnifiedTopology: true }); const userSchema = new mongoose.Schema({ email: String, password: String }); // Creating the User model. const User = new mongoose.model("User", userSchema); /* setting a simple get request on the home route, and sending our index.html file containing a form which will allow user to enter his details and register. */ app.get("/", function (req, res) { res.sendFile(__dirname + "/index.html"); }) app.get("/login", function(req, res) { res.sendFile(__dirname + "/login.html"); }) // Handling the post request on /register route. app.post("/register", function(req, res){ console.log(req.body); // Getting the email and password entered // by the user var email = req.body.username; var password = req.body.password; // Creating a new user with entered credentials. var newuser = new User({ email : email, password : password }) // Saving the newuser. newuser.save(); console.log("saved successfully"); // Sending the response that user // is saved successfully res.send("saved successfully"); }) APP.post("/login", function(req, res) { console.log(req.body); // Getting the email and password entered // by the user var emailEntered = req.body.username; var passwordEntered = req.body.password; // Checking if the email entered exists // in database or not. User.findOne({email : emailEntered}, function(err, data){ if(data) { // The email exists in the database. console.log(data); /* checking if the password entered is matching the original password */ if(data.password == passwordEntered){ res.send("login successful!"); } else { // Password is incorrect. res.send("Incorrect Password"); } } else { // The email does not exist in the database console.log(err); } }); }) // Allowing app to listen on port 3000 app.listen(3000, function () { console.log("server started successfully"); })
Index.html
<!DOCTYPE html> <html> <head> <title>Page Title</title> </head> <body> <form class="" action="/register" method="post"> <input type="email" name="username" placeholder="Name" value=""> <input type="password" name="password" placeholder="Password" value=""> <button type="submit" name="button"> Submit </button> </form> </body> </html>
Login.html
<!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title></title> </head> <body> <form class="" action="/login" method="post"> <input type="email" name="username" placeholder="Name" value=""> <input type="password" name="password" placeholder="Password" value=""> <button type="submit" name="button"> Submit </button> </form> </body> </html>
Pero existen algunas limitaciones en el uso de este método simple de autenticación.
- Las contraseñas ingresadas por el usuario en el proceso de registro quedan expuestas a todos en la base de datos , es decir, cualquier persona en la organización que tenga acceso a la base de datos puede ver la contraseña de cualquier usuario. Pero, las contraseñas no pueden dejarse expuestas y necesitamos un cifrado fuerte para que podamos almacenar nuestras contraseñas de forma segura en la base de datos.
- Cada vez (tal vez 20-25 veces al día o incluso más) que queremos usar esta aplicación web o sitio web, tenemos que volver a ingresar nuestro correo electrónico y contraseña, lo que consume mucho tiempo.
- No podemos agregar la función de inicio de sesión en redes sociales usando este código de autenticación simple.
Passport elimina todas estas limitaciones para nosotros. Si usamos Passport, entonces:
- No tenemos que dejar nuestras contraseñas expuestas. Passport realiza todo el procedimiento de cifrado y descifrado, incluido el hash y el cifrado de contraseñas.
- Passport nos permite crear y mantener sesiones. Por ejemplo, cuando visita cualquier sitio web de redes sociales o aplicación móvil, no tiene que iniciar sesión, una y otra vez, cada vez que quiera usar Instagram o Facebook. Más bien, la información se guarda, lo que significa que no tiene que iniciar sesión cada vez que desee utilizar el sitio web . En términos técnicos, se ha creado una sesión y se mantendrá durante los próximos días, semanas o meses.
- Passport también nos permite integrar fácilmente la autenticación usando Google, Facebook, LinkedIn y varios otros servicios de redes sociales.
Paso 7: Para usar el pasaporte, tenemos que instalar 4 paquetes npm, a saber, » pasaporte «, » pasaporte-local «, » pasaporte-local-mongoose » y » sesión rápida » (asegúrese de descargar «sesión rápida» y no “sesiones-express”).
En la línea de comando, escriba el siguiente comando para instalar los cuatro paquetes:
npm instalar pasaporte pasaporte-local pasaporte-local-mangoose express-session
Una vez que haya instalado, debe agregar el siguiente código en la parte superior del archivo Server.js para incluir el módulo de pasaporte.
Server.js
const session = require("express-session"); const passport = require("passport"); const passportLocalMongoose = require("passport-local-mongoose"); app.use(express.static("public")); app.use(bodyParser.urlencoded({extended:true})); // Below all the app.use methods app.use(session({ secret : "any long secret key", resave : false, saveUninitialized : false }));
Paso 8: Inicializar Passport e iniciar la sesión. Para inicializar Passport e iniciar la sesión, escriba el siguiente código justo debajo del código de declaración de la sesión.
Server.js
app.use(session({ secret: "any long secret key", resave: false, saveUninitialized: false })); // Initializing Passport app.use(passport.initialize()); // Starting the session app.use(passport.session()); // Creating user schema and adding a plugin to it const userSchema = new mongoose.Schema({ email: String, password: String }); userSchema.plugin(passportLocalMongoose);
Paso 9: Ahora, queremos que permanezcamos logueados durante un tiempo aunque cerremos la ventana del navegador, es decir, queremos que se establezca una sesión . La sesión utiliza una Cookie para almacenar los datos y mensajes y permite que el servidor proporcione datos de sesión correctos al Usuario. Proceso de creación de Cookies y almacenamiento de mensajes en ellas: Proceso de serialización de descomposición de Cookies y extracción de mensajes de las Cookies para que los datos correctos se entreguen al usuario:
Server.js
const User = new mongoose.model("User", userSchema); passport.use(User.createStrategy()); // Serializing and deserializing passport.serializeUser(User.serializeUser()); passport.deserializeUser(User.deserializeUser());
Paso 10: Ahora, estamos listos para agregar autenticación a nuestro sitio web. Instalamos los paquetes necesarios, configuramos la sesión, inicializamos Passport y la sesión, y le dijimos a Passport que usara y administrara las cookies.
Manejo de las requests de obtención:
Server.js
// Handling get request on the home and login route app.get("/", function (req, res) { /* req.isAuthentcated() returns true or false depending upon whether a session is already running or not.*/ if(req.isAuthenticated()) { /* if the request is already authenticated, i.e. the user has already logged in and there is no need to login again. Or we can say, the session is running. */ res.send(" You have already logged in. No need to login again"); } else{ // If the user is new and no session // is Running already res.sendFile(__dirname + "/index.html"); } }) // Handling get request on login route app.get("/login", function(req, res) { if(req.isAuthenticated()){ /* if request is already authenticated, i.e. user has already logged in and there is no need to login again. */ res.send(" You have already logged in. No need to login again"); } else{ res.sendFile(__dirname + "/login.html"); } })
Paso 11: Ahora, en la ruta de registro, debemos agregar un código simple que nos permitirá registrar cualquier nuevo usuario.
Server.js
/* The index.html file will be same as that used in the earlier method of authentication*/ app.post("/register", function(req, res){ console.log(req.body); // Getting Email and PAssword Entered by user var email = req.body.username; var password = req.body.password; /* Registering the user with email and password in our database and the model used is "User" */ User.register({ username : email }, req.body.password, function (err, user) { if (err) { // if some error is occurring, log that error console.log(err); } else { passport.authenticate("local") (req, res, function() { res.send("successfully saved!"); }) } }) })
Y el código similar es para manejar las requests de inicio de sesión. El siguiente es el código para manejar la solicitud de publicación en la ruta /login. (El archivo login.html será el mismo que se usó en el método de autenticación anterior)
Server.js
// All handling related to login is done below. // Here we are handling the post request on // /login route app.post("/login", function (req, res) { console.log(req.body); const userToBeChecked = new User({ username: req.body.username, password: req.body.password, }); // Checking if user if correct or not req.login(userToBeChecked, function (err) { if (err) { console.log(err); // If authentication fails, then coming // back to login.html page res.redirect("/login"); } else { passport.authenticate("local")( req, res, function () { User.find({ email: req.user.username }, function (err, docs) { if (err) { console.log(err); } else { //login is successful console.log("credentials are correct"); res.send("login successful"); } }); }); } }); });
Solo tiene que instalar todos los paquetes, escribir el siguiente código, iniciar el servidor (usando el comando «node server.js/node app.js») y estará listo para autenticar a sus usuarios usando Passport.
Index.html
<!DOCTYPE html> <html> <head> <title>Page Title</title> </head> <body> <h1>REGISTER</h1> <form class="" action="/register" method="post"> <input type="email" name="username" placeholder="Name" value=""> <input type="password" name="password" placeholder="Password" value=""> <button type="submit" name="button"> Submit </button> </form> </body> </html>
Login.html
<!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title></title> </head> <body> <h1>LOGIN</h1> <form class="" action="/login" method="post"> <input type="email" name="username" placeholder="Name" value=""> <input type="password" name="password" placeholder="Password" value=""> <button type="submit" name="button"> Submit </button> </form> </body> </html>
Server.js
var express = require('express'); var app = express(); const mongoose = require("mongoose"); /* Requiring body-parser package to fetch the data that is entered by the user in the HTML form.*/ const bodyParser = require("body-parser"); // Telling our Node app to include all these modules const session = require("express-session"); const passport = require("passport"); const passportLocalMongoose = require("passport-local-mongoose"); // Allowing app to use body parser app.use(bodyParser.urlencoded({ extended: true })); app.use(session({ secret: "long secret key", resave: false, saveUninitialized: false })); // Initializing Passport app.use(passport.initialize()); // Starting the session app.use(passport.session()); // Connecting mongoose to our database mongoose.connect( 'mongodb://localhost:27017/userDatabase', { useNewUrlParser: true, useUnifiedTopology: true }); /* Creating the schema of user which now include only email and password for simplicity.*/ const userSchema = new mongoose.Schema({ email: String, password: String }); /* Just after the creation of userSchema, we add passportLocalMongoose plugin to our Schema */ userSchema.plugin(passportLocalMongoose); // Creating the User model const User = new mongoose.model("User", userSchema); /* After the creation of mongoose model, we have to write the following code */ passport.use(User.createStrategy()); // Serializing and deserializing passport.serializeUser(User.serializeUser()); passport.deserializeUser(User.deserializeUser()); // Handling get request on the home route app.get("/", function (req, res) { /* req.isAuthentcated() returns true or false depending upon whether a session is already running or not. */ if (req.isAuthenticated()) { /* if request is already authenticated, i.e. user has already logged in and there is no need to login again or we can say, session is running.*/ res.send( "You have already logged in. No need to login again"); } else { // If the user is new and // no session is Running already res.sendFile(__dirname + "/index.html"); } }) // Handling get request on login route app.get("/login", function (req, res) { if (req.isAuthenticated()) { /* If request is already authenticated, i.e. user has already logged in and there is no need to login again. */ res.send( "You have already logged in. No need to login again"); } else { /* if session has expired, then user need to login back again and we will send the Login.html */ res.sendFile(__dirname + "/login.html"); } }) /* Registering the user for the first time handling the post request on /register route.*/ app.post("/register", function (req, res) { console.log(req.body); var email = req.body.username; var password = req.body.password; User.register({ username: email }, req.body.password, function (err, user) { if (err) { console.log(err); } else { passport.authenticate("local") (req, res, function () { res.send("successfully saved!"); }) } }) }) // Handling the post request on /login route app.post("/login", function (req, res) { console.log(req.body); const userToBeChecked = new User({ username: req.body.username, password: req.body.password }); // Checking if user if correct or not req.login(userToBeChecked, function (err) { if (err) { console.log(err); res.redirect("/login"); } else { passport.authenticate("local") (req, res,function () { User.find({ email: req.user.username }, function (err, docs) { if (err) { console.log(err); } else { //login is successful console.log("credentials are correct"); res.send("login successful"); } }); }); } }) }) // Allowing app to listen on port 3000 app.listen(3000, function () { console.log("server started successfully"); })
Usando este código y agregando la autenticación usando Passport, hemos eliminado los tres problemas principales:
- Una vez que iniciamos sesión, se crea una sesión. Esto significa que cada vez que volvemos a abrir el sitio, no necesitamos iniciar sesión una vez más. Las cookies se almacenaron en el navegador (cuando inició sesión por primera vez) y se utilizarán cuando regrese. (req.isAuthenticated() comprueba si una sesión ya se está ejecutando o no).
- Las contraseñas de nuestros usuarios están seguras. No quedan expuestos en nuestra base de datos. Hemos delegado toda la tarea de cifrado/descifrado a Passport y eso es todo.
- Podemos ver que ahora, no hay columna para «contraseña». Nuestras contraseñas están encriptadas por Passport. Y siempre que se necesiten para iniciar sesión, Passport puede descifrar las contraseñas y usarlas nuevamente.
- También podemos agregar autenticación usando Google, Facebook, LinkedIn y varios otros servicios de redes sociales usando solo Passport. (No lo hemos discutido aquí, pero el código es similar a este)
Producción:
Publicación traducida automáticamente
Artículo escrito por mananvirmani611 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA