Explain Passport in Node.js?


The Passport is a node package, or library which we can install in any nodeJs project. The Passport provides the functionality for authentication in the app. Also, it provides different encryption strategies to encrypt user information, such as a password.

For example, what if Facebook or Google employees could see the password of their users? It is against user privacy. So, in such cases, we can use the Passport, which encrypts the password and stores it in the database. We should know the decryption algorithm and secret key to decrypt the password.

Also, the Passport allows us to establish the authentication session for the users. Suppose you must log in again whenever you close the browser. It is time−consuming. Isn’t it? So, Passport allows us to establish a session for a particular time by storing the cookies in the browser. Users don't need to log in whenever a user visits the webpage within the particular session time set by the developers.

Here, we will create a basic authentication app and learn the use of the Passport with NodeJs.

Steps to Create an Application

Step 1 − Create the folder where you want to start the new NodeJs project.

Step 2 − Enter the below command to start a new Node project. It will create a package.json named file inside the project folder.

npm init -y

Step 3 − Users must install the required plugins for their node project. Open the terminal, go to the project directory, and enter the below command to install all NPM packages.

npm install express body-parser mongoose passport passport-local 
passport-local-mongoose express-session

In the above command, express is a web framework of the NodeJs. It allows users to create the nodeJs app server with fewer lines of code.

The body−parser is used to take the form−input data from the user. The Mongoose allows us to use the MongoDB database.

The passport NPM package is used for Passports in our app. The Passport−local contains around 450+ strategies to encrypt the data. The passport−local−mongoose uses MongoDB with Passport and express−session to maintain the login session using the Passport and express.

Step 4 − Now, let’s create a form to register the user. Create the register.html file in the project directory and paste the code below.

Example

<html>
<body>
   <h2>
      Enter email and password values, and press submit button for registration
   </h2>
   <!-- Make the post request on the /register route with email and password data -->
   <form action = "/register" method = "post">
      <input type = "email" name = "username" />
      <br />
      <input type = "password" name = "password" />
      <br />
      <button type = "submit" name = "button"> Submit </button>
   </form>
   </body>
</html>

In the above code, we have created the form that takes the users' email and password using the HTML form. We have created two different input fields for the email and password. Also, we have created the submit button, and when users press it, the app will make the post request at the ‘/register route.

Step 5 − Now, let’s create the code for the login page. Create the login.html file in the project directory and paste the below code.

Example

<html>
<body>
   <h2> Enter the credentials to log in to the app</h2>
   <!-- When the user presses the submit button, it makes a post request on the login route -->
   <form action = "/login" method = "post">
      <input type = "email" name = "username" />
      <br />
      <input type = "password" name = "password" />
      <br />
      <button type = "submit" name = "button"> Submit </button>
   </form>
   </body>
</html>

The above code is almost same as we have written in the register.html, but the difference is that it makes the post request on the ‘/login’ route when the user presses the submit button.

Step 6 − Now, we will start to create our server. We will import the required modules and initialize our app with a passport.

// Importing the required and installed modules
var express = require("express");
var app = express();
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const session = require("express-session");
const passport = require("passport");
const passportLocalMongoose = require("passport-local-mongoose");

// permitting the app to use body-parser without any error
app.use(bodyParser.urlencoded({ extended: true }));
app.use(
   session({
      secret: "This is the secret key to encrypt the password and user data.",
      resave: false,
      saveUninitialized: false,
   })
);

// initialize our app with passport and establish a session
app.use(passport.initialize());
app.use(passport.session());

We have imported the module and initialized our app with Passport in the above code. Also, we have established the session using the Passport.

Step 7 − We need to connect the MongoDB database with our application.

mongoose
.connect(
   "mongodb+srv://shubhamvora05:Stockdata@stockdata.lrlgm.mongodb.net/StockList?retryWrites=true&w=majority",
   { useNewUrlParser: true, useUnifiedTopology: true }
)
.then(() => {
   console.log("Connected to database successfully");
})
.catch((err) => {
   console.log("Error connecting to MongoDB database", err.message);
});

// creating the user schema containing the email_Adress and password field
const user = new mongoose.Schema({
   email_Address: String,
   password: String,
});

// code to use the Mongoose schema named user with passport
user.plugin(passportLocalMongoose);

// Creating the new model using the schema
const userModel = new mongoose.model("User", user);

// create the strategy to encrypt the data
passport.use(userModel.createStrategy());
passport.serializeUser(userModel.serializeUser());
passport.deserializeUser(userModel.deserializeUser());

We first connected our app with the MongoDB cluster in the above code. After that, we created the MongoDB schema named user to store the user’s authentication data. Next, we have plugin the user schema with the passortLocalMongoose NPM package. Also, we used the serializer and deserializer in the above code.

Step 8 − We need to handle the GET request from the home and login routes.

app.get("/", function (req, res) {
   if (req.isAuthenticated()) {
      res.send("Authenticated successfully");
   } else {
      res.sendFile(__dirname + "/register.html");
   }
});
app.get("/login", function (req, res) {
   if (req.isAuthenticated()) {
      res.send("Authenticated successfully");
   } else {
      res.sendFile(__dirname + "/login.html");
   }
});

In the above code, isAuthenticated() is the middleware function that checks whether a user is already logged in and sends the boolean value.

Step 9 − We must handle the POST request at the ‘/register’ route.

app.post("/register", function (req, res) {
   userModel.register(
      { username: req.body.username },
      req.body.password,
      function (err, user) {
         if (!err) {
            passport.authenticate("local")(req, res, function () {
               res.send("User registered successfully with email!");
            });
         }
      }
   );
});

In the above code, we used the passport.authenticate() method to encrypt the password and store it in the database.

Step 10 − Next, we need to handle the POST request at ‘/login’ route.

app.post("/login", function (req, res) {
   req.login(
      {
         username: req.body.username,
         password: req.body.password,
      },
      function (err) {
         if (!err) {
            passport.authenticate("local")(req, res, function () {
               userModel.find(
                  { email_Address: req.user.username },
                  (err) => {
                     if (!err) {
                        res.send("User login successful! Enjoy Now!");
                     }
                  }
               );
            });
         }
      }
   );
});

In the above code, we are getting the login credentials from the user. We are finding the user from the database and authenticating it using the passport. We send a message like “user login successful!” on authentication without error.

Step 11 − Create the server.js file and paste the below code.

// Importing the required and installed modules
var express = require("express");
var app = express();
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const session = require("express-session");
const passport = require("passport");
const passportLocalMongoose = require("passport-local-mongoose");

// give permission to the app to use body-parser without any error
app.use(bodyParser.urlencoded({ extended: true }));
app.use(
session({
   secret: "This is the secrect key to encrypt the password and user data.",
   resave: false,
   saveUninitialized: false,
   })
);

// initialize our app with passport and establish a session
app.use(passport.initialize());
app.use(passport.session());

// Connecting MongoDB cluster to our app using the mongoose NPM package
mongoose
.connect(
   "mongodb+srv://shubhamvora05:Stockdata@stockdata.lrlgm.mongodb.net/StockList?retryWrites=true&w=majority",
   { useNewUrlParser: true, useUnifiedTopology: true }
)
.then(() => {
   console.log("Connected to database successfully");
})
.catch((err) => {
   console.log("Error connecting to MongoDB database", err.message);
});

// creating the user schema containing the email_Adress and password field
const user = new mongoose.Schema({
   email_Address: String,
   password: String,
});

// code to use the Mongoose schema named user with passport
user.plugin(passportLocalMongoose);

// Creating the new model using the schema
const userModel = new mongoose.model("User", user);

// create the stratagy to encry the data
passport.use(userModel.createStrategy());
passport.serializeUser(userModel.serializeUser());
passport.deserializeUser(userModel.deserializeUser());

// handling the get request
// if user is authenticated then send response message "Authenticated successfullly"
// Othewise redirect user to register page.
app.get("/", function (req, res) {
   if (req.isAuthenticated()) {
      res.send("Authenticated successfully");
   } else {
      res.sendFile(__dirname + "/register.html");
   }
});

// Same like the register route,
// If user is authenticated then send response, othewise redirect to login route
app.get("/login", function (req, res) {
   if (req.isAuthenticated()) {
      res.send("Authenticated successfully");
   } else {
      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) {
   userModel.register(
      { username: req.body.username },
      req.body.password,
      function (err, user) {
         // registering using the passport
         if (!err) {
            passport.authenticate("local")(req, res, function () {
               res.send("User registered successfully with email!");
            });
         }
      }
   );
});

// Handling the post request on /login route
app.post("/login", function (req, res) {

   // requesting the login using passport
   req.login(
      {
         username: req.body.username,
         password: req.body.password,
      },
      function (err) {
         if (!err) {

            // authenticating using passport
            passport.authenticate("local")(req, res, function () {
               userModel.find(
                  { email_Address: req.user.username },
                  function (err, docs) {
                     if (!err) {
                        res.send("User login successful! Enjoy Now!");
                     }
                  }
               );
            });
         }
      }
   );
});

// Allowing the app to listen on port 3000
app.listen(3000, function () {
   console.log("server started successfully");
});

Step 12 − As the last step, we need to run our app. To run the app, enter the below command to the terminal.

node server.js

Updated on: 29-Dec-2022

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements