Explain passport in Node.js
Last Updated :
20 Aug, 2024
Passport is very easy to integrate NodeJs package, which is used for adding authentication features to our website or web app.
For showing the use of Passport in Nodejs, we are starting with creating a very simple Node app.
Creating a simple Node App using express:
Step 1: Create a new folder(I have named the folder "NODEAPP"), and create a new file named "Server.js" inside it.
Step 2: Initializing npm using the command "npm init -y". Package.json file will get added to your project folder.
npm init-y
Command used to initialize npm
Project Structure after running the command "npm init -y" Step 3: Install all the necessary packages, i.e, express, body-parser(will be used to fetch HTML form data later), mongoose(used to connect to our MongoDB database), using the command:
npm install express body-parser mongoose
The above command is to be executed to install the required packages.1 file, named "package-lock.json" will get added to your project structure, and 1 folder named "node_modules" will get added to your project structure after executing the above command.
Project Structure: The final project structure should look like this:
Final project structureStep 4: Adding basic code to our Server.js file.
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");
})
Step 5: You can also check by opening the browser and typing http://localhost:3000. You should see a white page with the following response.
The response you should get after you type "http://localhost:3000" in your browser.
Step 6: Adding authentication to our website. One simple way to add an authentication feature to our website is taking the email and password input from the user and directly saving them in the database. Similarly, when the user wants to log in, ask for his/her email and password, and if any record matches the entered email and password, then the user is authentic and the login is successful.
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>
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 */
const mongoose = require('mongoose')
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/todo',{
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");
})
But there are a few limitations in using this simple method of authentication.
- The passwords entered by the user in the registering process are left exposed to everyone in the database, i.e., anyone in the organization who has the access to the database can see any user's password. But, the passwords cannot be left exposed and we need strong encryption so that we can store our passwords safely in the database.
The password is exposed to everyone who is looking into the database.- Every time(maybe 20-25 times each day or even more than that) we want to use this web app or website, we have to re-enter our email and password, which becomes very time-consuming.
- We can not add social networking sign-in feature using this simple authentication code.
Passport eliminates all of these limitations for us. If we use Passport, then:
- We don't have to leave our passwords exposed. The whole encryption and decryption procedure is done by Passport including the hashing and encrypting of passwords.
- Passport allows us to create and maintain sessions. For example, when you visit any social media website or mobile app, you do not have to log in, again and again, each time you want to use Instagram or Facebook. Rather, the information is saved, which means you don't have to log in each time you want to use the website. In technical words, a session has been created, and it will be maintained for the next few days, or a few weeks, or a few months.
- Passport also allows us to easily integrate authentication using Google, Facebook, LinkedIn, and various other social networking services.
Step 7: For using passport, we have to install 4 npm packages, namely "passport", "passport-local", "passport-local-mongoose" and "express-session"(make sure that you download "express-session" and not "express-sessions").
In the command line, write the following command to install all the four packages:
npm install passport passport-local passport-local-mongoose express-session
Following command will install the required packages.Once you have installed, you need to add the following code at the top of the Server.js file to include the passport module.
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
}));
Step 8: Initializing Passport and starting the Session. For initializing Passport and starting the session, write the following code just below the session declaration code.
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);
Step 9: Now, we want that we remain logged in for some time even if we close the browser window, i.e., we want a session to be established. The session uses a Cookie to store the data and messages and allows the server to provide correct session data to the User. Process of creating Cookies and storing messages into it: Serializing Process of crumbling Cookies and extracting messages from the Cookies so that right data should be served to user:
Server.js
const User = new mongoose.model("User", userSchema);
passport.use(User.createStrategy());
// Serializing and deserializing
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
Step 10: Now, we are all set to add authentication to our website. We had installed the required packages, configured the session, initialized Passport and session, and told passport to use and manage cookies.
Handling the get requests:
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");
}
})
Step 11: Now, in the register route, we have to add simple code that will allow us to register any new user.
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!");
})
}
})
})
And the similar code is to handle login requests. Following is the code for handling the post request on the /login route.(The login.html file will be the same as that used in the earlier method of authentication )
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");
}
});
});
}
});
});
You just have to install all the packages, write the following code, start the server(using "node server.js/node app.js" command) and you are ready to Authenticate your Users using 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");
})
Using this code and adding authentication using Passport, we have eliminated the three major problems:
- Once we login, a session is created. This means whenever we open the site again, we need not to log in once more. Cookies got stored in the browser(when you logged in for the first time) and they will be used as and when you come back again. (req.isAuthenticated() checks whether a session is already running or not).
- Our Users' Passwords are safe. They are not left exposed in our database. We have delegated all the encryption/decryption task to Passport and that's it.
Passwords are encrypted and are not visible to anyone.
- We can see that now, there is no column for "password". Our passwords are encrypted by Passport. And whenever they are needed for log in purpose, Passport can again decrypt the passwords and use them.
- We can also add authentication using Google, Facebook, LinkedIn, and various other Social Networking Services using Passport only.(We have not discussed it here but the code is similar to this)
Output:
Similar Reads
Node.js Tutorial Node.js is a powerful, open-source, and cross-platform JavaScript runtime environment built on Chrome's V8 engine. It allows you to run JavaScript code outside the browser, making it ideal for building scalable server-side and networking applications.JavaScript was mainly used for frontend developme
4 min read
Introduction & Installation
NodeJS IntroductionNodeJS is a runtime environment for executing JavaScript outside the browser, built on the V8 JavaScript engine. It enables server-side development, supports asynchronous, event-driven programming, and efficiently handles scalable network applications. NodejsNodeJS is single-threaded, utilizing an e
4 min read
Node.js Roadmap: A Complete GuideNode.js has become one of the most popular technologies for building modern web applications. It allows developers to use JavaScript on the server side, making it easy to create fast, scalable, and efficient applications. Whether you want to build APIs, real-time applications, or full-stack web apps
6 min read
How to Install Node.js on LinuxInstalling Node.js on a Linux-based operating system can vary slightly depending on your distribution. This guide will walk you through various methods to install Node.js and npm (Node Package Manager) on Linux, whether using Ubuntu, Debian, or other distributions.PrerequisitesA Linux System: such a
6 min read
How to Install Node.js on WindowsInstalling Node.js on Windows is a straightforward process, but it's Important to follow the right steps to ensure smooth setup and proper functioning of Node Package Manager (NPM), which is Important for managing dependencies and packages. This guide will walk you through the official site, NVM, Wi
5 min read
How to Install NodeJS on MacOSNode.js is a popular JavaScript runtime used for building server-side applications. Itâs cross-platform and works seamlessly on macOS, Windows, and Linux systems. In this article, we'll guide you through the process of installing Node.js on your macOS system.What is Node.jsNode.js is an open-source,
6 min read
Node.js vs Browser - Top Differences That Every Developer Should KnowNode.js and Web browsers are two different but interrelated technologies in web development. JavaScript is executed in both the environment, node.js, and browser but for different use cases. Since JavaScript is the common Programming language in both, it is a huge advantage for developers to code bo
6 min read
NodeJS REPL (READ, EVAL, PRINT, LOOP)NodeJS REPL (Read-Eval-Print Loop) is an interactive shell that allows you to execute JavaScript code line-by-line and see immediate results. This tool is extremely useful for quick testing, debugging, and learning, providing a sandbox where you can experiment with JavaScript code in a NodeJS enviro
4 min read
Explain V8 engine in Node.jsThe V8 engine is one of the core components of Node.js, and understanding its role and how it works can significantly improve your understanding of how Node.js executes JavaScript code. In this article, we will discuss the V8 engineâs importance and its working in the context of Node.js.What is a V8
7 min read
Node.js Web Application ArchitectureNode.js is a JavaScript-based platform mainly used to create I/O-intensive web applications such as chat apps, multimedia streaming sites, etc. It is built on Google Chromeâs V8 JavaScript engine. Web ApplicationsA web application is software that runs on a server and is rendered by a client browser
3 min read
NodeJS Event LoopThe event loop in Node.js is a mechanism that allows asynchronous tasks to be handled efficiently without blocking the execution of other operations. It:Executes JavaScript synchronously first and then processes asynchronous operations.Delegates heavy tasks like I/O operations, timers, and network r
5 min read
Node.js Modules , Buffer & Streams
NodeJS ModulesIn NodeJS, modules play an important role in organizing, structuring, and reusing code efficiently. A module is a self-contained block of code that can be exported and imported into different parts of an application. This modular approach helps developers manage large projects, making them more scal
5 min read
What are Buffers in Node.js ?Buffers are an essential concept in Node.js, especially when working with binary data streams such as files, network protocols, or image processing. Unlike JavaScript, which is typically used to handle text-based data, Node.js provides buffers to manage raw binary data. This article delves into what
4 min read
Node.js StreamsNode.js streams are a key part of handling I/O operations efficiently. They provide a way to read or write data continuously, allowing for efficient data processing, manipulation, and transfer.\Node.js StreamsThe stream module in Node.js provides an abstraction for working with streaming data. Strea
4 min read
Node.js Asynchronous Programming
Node.js NPM
Node.js Deployments & Communication
Node DebuggingDebugging is an essential part of software development that helps developers identify and fix errors. This ensures that the application runs smoothly without causing errors. NodeJS is a JavaScript runtime environment that provides various debugging tools for troubleshooting the application.They help
2 min read
How to Perform Testing in Node.js ?Testing is a method to check whether the functionality of an application is the same as expected or not. It helps to ensure that the output is the same as the required output. How Testing can be done in Node.js? There are various methods by which tasting can be done in Node.js, but one of the simple
2 min read
Unit Testing of Node.js ApplicationNode.js is a widely used javascript library based on Chrome's V8 JavaScript engine for developing server-side applications in web development. Unit Testing is a software testing method where individual units/components are tested in isolation. A unit can be described as the smallest testable part of
5 min read
NODE_ENV Variables and How to Use Them ?Introduction: NODE_ENV variables are environment variables that are made popularized by the express framework. The value of this type of variable can be set dynamically depending on the environment(i.e., development/production) the program is running on. The NODE_ENV works like a flag which indicate
2 min read
Difference Between Development and Production in Node.jsIn this article, we will explore the key differences between development and production environments in Node.js. Understanding these differences is crucial for deploying and managing Node.js applications effectively. IntroductionNode.js applications can behave differently depending on whether they a
3 min read
Best Security Practices in Node.jsThe security of an application is extremely important when we build a highly scalable and big project. So in this article, we are going to discuss some of the best practices that we need to follow in Node.js projects so that there are no security issues at a later point of time. In this article, we
4 min read
Deploying Node.js ApplicationsDeploying a NodeJS application can be a smooth process with the right tools and strategies. This article will guide you through the basics of deploying NodeJS applications.To show how to deploy a NodeJS app, we are first going to create a sample application for a better understanding of the process.
5 min read
How to Build a Microservices Architecture with NodeJSMicroservices architecture allows us to break down complex applications into smaller, independently deployable services. Node.js, with its non-blocking I/O and event-driven nature, is an excellent choice for building microservices. How to Build a Microservices Architecture with NodeJS?Microservices
3 min read
Node.js with WebAssemblyWebAssembly, often abbreviated as Wasm, is a cutting-edge technology that offers a high-performance assembly-like language capable of being compiled from various programming languages such as C/C++, Rust, and AssemblyScript. This technology is widely supported by major browsers including Chrome, Fir
3 min read
Resources & Tools
Node.js Web ServerA NodeJS web server is a server built using NodeJS to handle HTTP requests and responses. Unlike traditional web servers like Apache or Nginx, which are primarily designed to give static content, NodeJS web servers can handle both static and dynamic content while supporting real-time communication.
6 min read
Node Exercises, Practice Questions and SolutionsNode Exercise: Explore interactive quizzes, track progress, and enhance coding skills with our engaging portal. Ideal for beginners and experienced developers, Level up your Node proficiency at your own pace. Start coding now! #content-iframe { width: 100%; height: 500px;} @media (max-width: 768px)
4 min read
Node.js ProjectsNode.js is one of the most popular JavaScript runtime environments widely used in the software industry for projects in different domains like web applications, real-time chat applications, RESTful APIs, microservices, and more due to its high performance, scalability, non-blocking I/O, and many oth
9 min read
NodeJS Interview Questions and AnswersNodeJS is one of the most popular runtime environments, known for its efficiency, scalability, and ability to handle asynchronous operations. It is built on Chromeâs V8 JavaScript engine for executing JavaScript code outside of a browser. It is extensively used by top companies such as LinkedIn, Net
15+ min read