Explicar el pasaporte en Node.js

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

Comando utilizado para inicializar npm

Estructura del proyecto después de ejecutar el comando «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

El comando anterior debe ejecutarse para instalar los paquetes necesarios.

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í: 

Estructura del proyecto final

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.

La respuesta que debe obtener después de escribir «http://localhost:3000» en su navegador.

Creando la aplicación Node básica y verificando si todo está bien hasta ahora.

 

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.

La contraseña está expuesta a todos los que buscan 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

El siguiente comando instalará los paquetes necesarios.

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.

Las contraseñas están encriptadas y no son visibles para nadie.

  • 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

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *