Implementing Passport Authentication In Express Node.js


This is the second part of the Building An App Using Express, Sequelize and MySQL tutorial series. In this tutorial, you’ll learn how to go about implementing passport authentication in Express Node.js. You’ll be implementing the passport local strategy in this passport authentication example.

Source code from this tutorial is available on GitHub.

Getting Started

Let’s get started by cloning the source code from the first part of the tutorial series.

  • Clone the source code

    clone the source code to a folder

    git clone https://github.com/codehandbook/task_management_setting_up passport_auth

  • Install the required dependencies

    install dependencies

    npm install

  • Modify the config/config.json file as per your development database Once you have an empty database schema in your local MySQL database, migrate and seed the table and dummy data

    node_modules/.bin/sequelize db:migrate node_modules/.bin/sequelize db:seed:all

  • Run the applicaion

    running the app

    DEBUG=taskmanagement:* npm start

You will have the application up and running at http://localhost:3000/.

Creating the User Login Screen

You’ll be using bootstrap to design our application. Let’s start installing bootstrap into our application.

# install bootstrap using npm
npm install bootstrap --save

Inside the app.js file define the static paths for the bootstrap and public directory as shown:

app.use('/public', express.static(path.join(__dirname, 'public')));
app.use('/bootstrap', express.static(path.join(__dirname, '/node_modules/bootstrap/dist/')));

Add the following signin.css file inside the public/stylesheets folder.

html,
body {
  height: 100%;
}

body {
  display: -ms-flexbox;
  display: flex;
  -ms-flex-align: center;
  align-items: center;
  padding-top: 40px;
  padding-bottom: 40px;
  background-color: #f5f5f5;
}

.form-signin {
  width: 100%;
  max-width: 330px;
  padding: 15px;
  margin: auto;
}
.form-signin .checkbox {
  font-weight: 400;
}
.form-signin .form-control {
  position: relative;
  box-sizing: border-box;
  height: auto;
  padding: 10px;
  font-size: 16px;
}
.form-signin .form-control:focus {
  z-index: 2;
}
.form-signin input[type="email"] {
  margin-bottom: -1px;
  border-bottom-right-radius: 0;
  border-bottom-left-radius: 0;
}
.form-signin input[type="password"] {
  margin-bottom: 10px;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}

Create a view for the sign in page. Replace the existing HTML code with the following HTML code in views/index.ejs.

    Signin Template for Bootstrap

    
    

    
    
    
  

  
    
      
      Please sign in
      Email address
      
      Password
      
      
        
           Remember me
        
      
      Sign in
      © 2017-2018

Save the above changes and restart the Express application server. Point your browser to http://localhost:3000/ and you will have the sign in page displayed.

[caption id=“attachment_1546” align=“aligncenter” width=“720”]Express SignIn Page Express SignIn Page[/caption]

Adding Passport Authentication In Express Node.js

In this tutorial, you’ll implementing passport authentication in express Node.js using local strategy. Local strategy is used to authenticate users using a username and password.

To get started you need to install passport and passport-local in your express web app.

npm install passport --save
npm install passport-local --save

Once you have installed the above dependencies you need to require them inside the app.js file.

const passport = require('passport');
const Strategy = require('passport-local').Strategy;

Create a new route called login.js inside routes folder. Add the following code to routes/login.js file :

const express = require('express');
const router = express.Router();
const passport = require('passport');

/* GET Login Index page. */
router.get('/', function(req, res) {
    res.render('index');
});

/* POST Validate the user login */
router.post('/validate', passport.authenticate('local', { failureRedirect: '/' }),
    function(req, res) {
        res.redirect('/home');
    });

module.exports = router;

Include login.js route in the app module in app.js.

const loginRouter = require('./routes/login');
app.use('/login', loginRouter);

You need to add passport and passport session to the app. Add the following to app.js file :

app.use(passport.initialize());
app.use(passport.session());

You need to define the authentication strategy that passport needs to use to validate a request. Add the following code to app.js file :

passport.use(new Strategy({
    usernameField: 'email',
    passwordField: 'password'
},
function(username, password, cb) {
    db.User.findOne({
        where: {
            email: username
        },
        raw : true
    }).then(function(user){
        if (!user) { return cb(null, false); }
        if (user.password != password) { return cb(null, false); }
        return cb(null, user);
    }).catch(function(error){
        if (error) { return cb(null, error); }
    });
}));

As seen in the above code, passport uses the username to search for the user inside the database using the sequelize db object. If the password of the user found from database table matches with the argument password, the user is returned back.

You’ll also need the passport serialize and de-serialize method to store the user information in session and to retrieve back the stored information from session respectively.

If interested you can have a look at a detailed discussion on why we need serialize and deserialize in Passport.

Here is how the serialize and deserialize methods looks :

passport.serializeUser(function(user, cb) {
    cb(null, user.email);
});

passport.deserializeUser(function(username, cb) {
    db.User.findOne({
        where: {
            email: username
        },
        raw : true
    }).then(function(user) {
        cb(null, user.id);
    });
});

Add a new route called home.js in routes folder. Here is how home.js looks :

const express = require('express');
const router = express.Router();

router.get('/', function(req, res){
    res.render('home');
});

module.exports = router;

Add the home route to app module in app.js.

const homeRouter = require('./routes/home');
app.use('/home', homeRouter);

Create a view called home.ejs in views folder. Add the following HTML code to home.ejs file :

    Album example for Bootstrap

    
   

    
    
  

  

    
      
        
          
            
              About
              Add some information about the album below, the author, or any other background context. Make it a few sentences long so folks can pick up some informative tidbits. Then, link them off to some social networking sites or contact information.
            
            
              Contact
              
                Follow on Twitter
                Like on Facebook
                Email me
              
            
          
        
      
      
        
          
            
            Album
          
          
            
          
        
      
    

    

      
        
          Album example
          Something short and leading about the collection below—its contents, the creator, etc. Make it short and sweet, but not too short so folks don't simply skip over it entirely.
          
            Main call to action
            Secondary action
          
        
      

      
        

          
            
              
                
                
                  This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
                  
                    
                      View
                      Edit
                    
                    9 mins
                  
                
              
            
            
              
                
                
                  This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
                  
                    
                      View
                      Edit
                    
                    9 mins
                  
                
              
            
            
              
                
                
                  This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
                  
                    
                      View
                      Edit
                    
                    9 mins
                  
                
              
            

            
              
                
                
                  This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
                  
                    
                      View
                      Edit
                    
                    9 mins
                  
                
              
            
            
              
                
                
                  This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
                  
                    
                      View
                      Edit
                    
                    9 mins
                  
                
              
            
            
              
                
                
                  This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
                  
                    
                      View
                      Edit
                    
                    9 mins
                  
                
              
            

            
              
                
                
                  This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
                  
                    
                      View
                      Edit
                    
                    9 mins
                  
                
              
            
            
              
                
                
                  This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
                  
                    
                      View
                      Edit
                    
                    9 mins
                  
                
              
            
            
              
                
                
                  This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
                  
                    
                      View
                      Edit
                    
                    9 mins
                  
                
              
            
          
        
      

    

    
      
        
          Back to top
        
        Album example is © Bootstrap, but please download and customize it for yourself!
        New to Bootstrap? Visit the homepage or read our getting started guide.

Save the above changes and restart the application. Try to sign in using an existing username and password and you’ll be redirected to the home page.

Authenticating Routes Using Passport

If you try to access the http://localhost:3000/home without actually signing in, you are able to view the home page. In order to restrict or authenticate routes you need to add a middleware which checks if the request is authenticated.

Inside the project create a folder called middlewares. Inside middlewares folder create a file called authentication.js. Add the following code to authentication.js file :

module.exports = {
    isAuthenticated : function(req, res, next) {
        if(req.isAuthenticated()) {
            next();
        }
        res.redirect('/login');
    }
};

Once you have authenticated using passport the req.isAuthenticated method returns true. You have used to check if the request is authenticated or not.

Require the authentication.js file in home.js and add the above method as a middleware. Here is how the routes/home.js file looks :

const express = require('express');
const router = express.Router();
const auth = require('../middlewares/authentication');

router.get('/', auth.isAuthenticated , function(req, res){
    res.render('home');
});

module.exports = router;

Save the above changes and restart the server. Try to access /home route without signing in and you’ll be redirected to the login page.

Wrapping It Up

In this tutorial, you learnt how to implement Passport Authentication In Express Node.js using local strategy. In the next part of the tutorial series, you’ll learn how to implement the functionality for the Admin page role.

Do let us know your thoughts in the comments below.