Search

Authenticate Users With Node ExpressJS and Passport.js

post-title

Today, Node Js one of the most popular languages to develop web applications. because node js have more power to handle the large scale data and real-time event processing. many most popular web applications use node js for a backend for real-time data handling. so, today we will share with you very basic functionality on how to make user login authentication using a passport in node js.

Login functionality is one of the basic requirements in any web application. in this article, we will make login authentication in node js using a passport. passport provides us with authentication functions for a login system.

What did we do in this Article?

In this article, we will make a simple login system in node js using a passport. but here we not use any database to store our register data. we will store all register data into a session. this article we write for understood how to passport work in node js. in a future article we will also make one another article in that article we will user MongoDB database for store our register data.

Table of Contents

  • Step 1 : Install the Node Js
  • Step 2 : Create package.json File
  • Step 3 : Install Required Package
  • Step 4 : Create .env file
  • Step 5 : Create index.ejs File
  • Step 6 : Create login.ejs File
  • Step 7 : Create register.ejs File
  • Step 8 : Create passport-config.js File
  • Step 9 : Create server.js File
  • Step 10 : Run Application in Browser

Directory Structure :

passportlogin
├── node_modules
├── views
│   ├── index.ejs
│   ├── login.ejs
│   ├── register.ejs
├── package.json
├── .env
├── passport-config.js
└── server.js

Step - 1 : Install the Node Js

In the first step, we need to install nodejs in our local system. please follow the article and first install the nodejs if you have not installed in your system.

Step - 2 : Create package.json File

Now, go to your application folder's root path and first create the package.json file by running this command.

npm init

After, hit this command in your terminal then put all the required data for and first done it. then your package.json the file looks like.

{
  "name": "User-Login-Authentication-With-Passport",
  "version": "1.0.0",
  "description": "how to make login system in nodejs",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
  },
  "keywords": [
  ],
  "author": "Harsukh Makwana",
  "license": "ISC"
}

Step - 3 : Install Package

After, done the create package.json the file then we need to install some required package for our node js application. here is all the required package list. and install one by one run the command in your terminal.

npm i express ejs
npm i --save-dev nodemon dotenv
npm i bcrypt
npm i passport 
npm i passport-local 
npm i express-session 
npm i express-flash
npm i method-override

After, install all the required packages in your application then open the package.json file and change the following. then our package.json file will look like.

{
  "name": "User-Login-Authentication-With-Passport",
  "version": "1.0.0",
  "description": "how to make login system in nodejs",
  "main": "index.js",
  "scripts": {
    "devStart": "nodemon server.js"
  },
  "keywords": [
  ],
  "author": "Harsukh Makwana",
  "license": "ISC",
  "dependencies": {
    "bcrypt": "^3.0.7",
    "ejs": "^3.0.1",
    "express": "^4.17.1",
    "express-flash": "0.0.2",
    "express-session": "^1.17.0",
    "method-override": "^3.0.0",
    "passport": "^0.4.1",
    "passport-local": "^1.0.0"
  },
  "devDependencies": {
    "dotenv": "^8.2.0",
    "nodemon": "^2.0.2"
  }
}

Step - 4 : Create .env file

Now, create .env file on your application root folder and put the following content in it.

SESSION_SECRET=secret

Step - 5 : Create index.ejs File

Now, we need to create views/index.ejs file and write the following HTML code into it. this file will be we use before login for an entry point and after login in this file, we will simply print the login user's name.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="">
  <meta name="author" content="Harsukh Makwana">
  <title>Node Js Passport Authentication - laravelcode</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
  <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
</head>
<body>
  <div class="container">
    <div class="row">
      <div class="col-lg-12 text-center">
        <h1 class="mt-5">Node Js Passport Authentication - laravelcode</h1>
        <h1>Hi <%= name %></h1>
        <form action="/logout?_method=DELETE" method="POST">
          <button type="submit" class="btn btn-danger">Sign Out</button>
        </form>
      </div>
    </div>
  </div>
</body>
</html>

Step - 6 : Create login.ejs File

Now, we need to create views/login.ejs a file for the login form and write the following simple login HTML form code there.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="">
  <meta name="author" content="Harsukh Makwana">
  <title>Node Js Passport Authentication - laravelcode</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
  <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
</head>
<body>
  <div class="container">
    <div class="row">
      <div class="col-lg-12">
        <h1 class="mt-5 text-center">Login</h1>
        <div class="col-lg-6 offset-3">
          <% if (messages.error) { %>
            <div class="alert alert-danger alert-dismissible">
              <button type="button" class="close" data-dismiss="alert">&times;</button>
              <strong>Error!</strong> <%= messages.error %> 
            </div>
          <% } %>
          <form action="/login" method="POST">
            <div class="form-group">
              <label for="email">Email</label>
              <input type="email" class="form-control" id="email" name="email" placeholder="Enter Email" required>
            </div>
            <div class="form-group">
              <label for="password">Password</label>
              <input type="password" class="form-control" id="password" name="password" placeholder="Enter Password" required>
            </div>
            <button type="submit" class="btn btn-success">Sign In</button>
            <a href="/register" class="btn btn-primary">Sign Up</a>
          </form>
        </div>
      </div>
    </div>
  </div>
</body>
</html>

Step - 7 : Create register.ejs File

Now, we need to create views/register.ejs a file for the registration form and write the following simple register HTML form code there.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="">
  <meta name="author" content="Harsukh Makwana">
  <title>Node Js Passport Authentication - laravelcode</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
  <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
</head>
<body>
  <div class="container">
    <div class="row">
      <div class="col-lg-12">
        <h1 class="mt-5 text-center">Register</h1>
        <div class="col-lg-6 offset-3">
          <form action="/register" method="POST">
            <div class="form-group">
              <label for="name">Name</label>
              <input type="text" class="form-control" id="name" name="name" placeholder="Enter Name" required>
            </div>
            <div class="form-group">
              <label for="email">Email</label>
              <input type="email" class="form-control" id="email" name="email" placeholder="Enter Email" required>
            </div>
            <div class="form-group">
              <label for="password">Password</label>
              <input type="password" class="form-control" id="password" name="password" placeholder="Enter Password" required>
            </div>
            <button type="submit" class="btn btn-success">Sign Up</button>
            <a href="/login" class="btn btn-primary">Sign In</a>
          </form>
        </div>
      </div>
    </div>
  </div>
</body>
</html>

Step - 8 : Create passport-config.js File

In this step, we will create passport-confige.js file and write our passport authentication login into this file.

const LocalStrategy = require('passport-local').Strategy
const bcrypt = require('bcrypt')

function initialize(passport, getUserByEmail, getUserById) {
  const authenticateUser = async (email, password, done) => {
    const user = getUserByEmail(email)
    if (user == null) {
      return done(null, false, { message: 'No user with that email' })
    }

    try {
      if (await bcrypt.compare(password, user.password)) {
        return done(null, user)
      } else {
        return done(null, false, { message: 'Password incorrect' })
      }
    } catch (e) {
      return done(e)
    }
  }

  passport.use(new LocalStrategy({ usernameField: 'email' }, authenticateUser))
  passport.serializeUser((user, done) => done(null, user.id))
  passport.deserializeUser((id, done) => {
    return done(null, getUserById(id))
  })
}

module.exports = initialize

Step - 9 : Create server.js File

In the last step, we will create our main server.js file for our core login.

if (process.env.NODE_ENV !== 'production') {
  require('dotenv').config()
}

const express = require('express')
const app = express()
const bcrypt = require('bcrypt')
const passport = require('passport')
const flash = require('express-flash')
const session = require('express-session')
const methodOverride = require('method-override')

const initializePassport = require('./passport-config')
initializePassport(
  passport,
  email => users.find(user => user.email === email),
  id => users.find(user => user.id === id)
)

// Assign empty array in users
const users = []

app.set('view-engine', 'ejs')
app.use(express.urlencoded({ extented: false }))
app.use(flash())
app.use(session({
  secret: process.env.SESSION_SECRET,
  resave: false,
  saveUninitialized: false
}))
app.use(passport.initialize())
app.use(passport.session())
app.use(methodOverride('_method'))

// Home page route
app.get('/', checkAuthenticated, (req, res) => {
  res.render('index.ejs', { name: req.user.name })
})

// Login page route
app.get('/login', checkNotAuthenticated, (req, res) => {
  res.render('login.ejs')
})

// Logim post route
app.post('/login', checkNotAuthenticated, passport.authenticate('local', {
  successRedirect: '/',
  failureRedirect: '/login',
  failureFlash: true
}))

// Register page route
app.get('/register', checkNotAuthenticated, (req, res) => {
  res.render('register.ejs')
})

// Register post route
app.post('/register', checkNotAuthenticated, async (req, res) => {
  try {
    const hashedPassword = await bcrypt.hash(req.body.password, 10)
    users.push({
      id: Date.now().toString(),
      name: req.body.name,
      email: req.body.email,
      password: hashedPassword
    })
    res.redirect('/login')
  } catch {
    res.redirect('/register')
  }
})

// Logout route
app.delete('/logout', (req, res) => {
  req.logOut()
  res.redirect('/login')
})

// Check if user Authenticated
function checkAuthenticated(req, res, next) {
  if (req.isAuthenticated()) {
    return next()
  }
  res.redirect('/login')
}

// Check if user Not Authenticated
function checkNotAuthenticated(req, res, next) {
  if (req.isAuthenticated()) {
    return res.redirect('/')
  }
  next()
}

app.listen(3000)

Step - 10 : Run Application in Browser

Now, into the last how to run this node js application in a web browser. so, simply run the following command into the terminal on your node js application root path.

sudo npm run devStart

After the hit command in your terminal then the output will be shown into the terminal looks like.

> passportlogin@1.0.0 devStart /var/www/nodejs/passportlogin
> nodemon server.js

[nodemon] 2.0.2
[nodemon] to restart at any time, enter `rs`
[nodemon] watching dir(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node server.js`

Now, your passport login application ready to run open your web browser and hit the following URL into it.

http://localhost:3000

Conclusion

You can see how to make user's login authentication in node js is very easy using of passport. You can check I hope you will like this article.