Node Authentication using passport.js - Part 1
Tags: node, passport
Published: 2019-04-23 06:34:05

---
title: Node Authentication using passport.js - Part 1
published: true
description: passport is an authentication middleware for node application. passport provides different set of strategies using a username and password, Facebook and Twitter.
tags: nodejs, passport
---

<p>Authentication for a web application is difficult to setup manually.To make it easier, passport came into action.</p>



<h3>What is Passport?</h3>



<p>passport is an authentication middleware for node application. passport provides different set of strategies using a username and password, Facebook and Twitter.</p>



<p>The article is separated as two parts for better understanding of the passport authentication concepts</p>



<p>we can use different ways to login in a web application such as Facebook,Twitter, Google and local(username and password)</p>


<p>In this article, we will use local strategy for the web application and folder structure will looks like:</p>


<h4>Project Structure :</h4>


<figure class="wp-block-image"><img src="https://cloudnweb.dev/wp-content/uploads/2019/04/Screen-Shot-2019-04-19-at-12.25.37-PM.png" alt="" class="wp-image-273"/></figure>


<p>Firstly, we are going to install all the dependencies needed for an application. Therefore, we install the packages needed for an application</p>

<pre class="wp-block-code"><code>"dependencies": {
    "bcrypt-nodejs": "0.0.3",
    "body-parser": "^1.18.3",
    "connect-flash": "^0.1.1",
    "cookie-parser": "^1.4.4",
    "cors": "^2.8.5",
    "express": "^4.16.4",
    "express-handlebars": "^3.0.2",
    "express-session": "^1.16.1",
    "method-override": "^3.0.0",
    "mongoose": "^5.5.2",
    "morgan": "^1.9.1",
    "passport": "^0.4.0",
    "passport-local": "^1.0.0"
  },</code></pre>

<p>Most importantly, <strong>passport</strong> and <strong>passport-local</strong> are the packages are used for passport authentication.</p>


<p>on the other hand, we need to create <strong>models </strong>which is nothing but Schema for user. create a file called <strong>user.schema.js</strong></p>


<pre class="wp-block-code"><code>const mongoose = require('mongoose');
const  bcrypt   = require('bcrypt-nodejs');
const Schema = mongoose.Schema;

let userschema = new Schema({
    email : String,
    password : String,
});

userschema.methods.generateHash = function(password) {
    return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};

// checking if password is valid
userschema.methods.validPassword = function(password) {
    return bcrypt.compareSync(password, this.password);
};


let User = mongoose.model('User',userschema);

module.exports = User;</code></pre>

<p>we need to create a file called <strong>passport</strong> where we need to setup the passport strategy. that is to say, create a file called <strong>config/passport.js .  </strong></p>

<p>Firstly, we will see how to setup the signup using passport authentication.Therefore, add the following code in the <strong>config/passport.js</strong></p>


<pre class="wp-block-code"><code>const LocalStrategy = require('passport-local').Strategy;

let User = require('../models/user.schema');

module.exports = function(passport){

    // used to serialize the user for the session
    passport.serializeUser(function(user, done) {
        done(null, user.id);
    });

    // used to deserialize the user
    passport.deserializeUser(function(id, done) {
        User.findById(id, function(err, user) {
            done(err, user);
        });
    });

    passport.use('local-signup', new LocalStrategy({
        // by default, local strategy uses username and password, we will override with email
        usernameField : 'email',
        passwordField : 'password',
        passReqToCallback : true // allows us to pass back the entire request to the callback
    },
    function(req, email, password, done) {

        // asynchronous
        // User.findOne wont fire unless data is sent back
        process.nextTick(function() {

        // find a user whose email is the same as the forms email
        // we are checking to see if the user trying to login already exists
        User.findOne({ 'email' :  email }, function(err, user) {
            // if there are any errors, return the error
            if (err)
                return done(err);

            // check to see if theres already a user with that email
            if (user) {
                return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
            } else {

                // if there is no user with that email
                // create the user
                var newUser            = new User();

                // set the user's local credentials
                
                newUser.email    = email;
                newUser.password = newUser.generateHash(password);

                // save the user
                newUser.save(function(err) {
                    if (err)
                        throw err;
                    return done(null, newUser);
                });
            }

        });    

        });

    }));
}</code></pre>


<p>In the above file, we setup the passport local strategy for signup and insert the user into the database.</p>



<p>After that, we need to create a <strong>route</strong> file  where we need to handle the signup url.So,create a file called <strong>routes/index.js</strong></p>


<pre class="wp-block-code"><code>
module.exports = function(app,passport){

    app.get('/',isLoggedIn,(req,res)=>{
        console.log("req user",req.user);
        res.render('home',{
            user : req.user
        });
    });

    app.get('/signup',(req,res) => {
        res.render('signup');
    })

    app.post('/signup', passport.authenticate('local-signup', {
        successRedirect : '/', // redirect to the secure profile section
        failureRedirect : '/signup', // redirect back to the signup page if there is an error
        failureFlash : true // allow flash messages
    }));

    app.get('/logout', function(req, res) {
        req.logout();
        res.redirect('/');
    });


        // route middleware to make sure a user is logged in
    function isLoggedIn(req, res, next) {

        // if user is authenticated in the session, carry on 
        if (req.isAuthenticated())
            return next();

        // if they aren't redirect them to the home page
        res.redirect('/login');
    }
}</code></pre>


<!-- wp:paragraph -->
<p>So far, we added the route for signup and after successful signup, we redirect them to home page. So, we need to create view files for signup and home page.</p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>create a folder called <strong>views </strong>and add the the following files</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>    - views
       - layouts
        ------ main.handlebars  &lt;!-- show our home page with 
    ------ home.handlebars    &lt;!-- show our home -->
    ------ login.handlebars   &lt;!-- show our login form --></code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>that is to say,  <strong>main.hanldebars</strong> should looks like</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>&lt;!DOCTYPE html>
&lt;html>
&lt;head>
    &lt;meta charset="utf-8">
    &lt;title>Worker App&lt;/title>
    &lt;link rel="icon" href="/images/favicon.png"/>
    &lt;link  rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css"/>
&lt;/head>
&lt;body>

    {body}

&lt;/body>
&lt;/html></code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p><strong>signup.handlebars</strong> should looks like</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>
    {#if message }
        &lt;div class="ui negative message transition hidden">
            &lt;i class="close icon">&lt;/i>
            &lt;div class="header">
                {message}
            &lt;/div>
        &lt;/div>
    {/if}
    &lt;div class="ui middle aligned center aligned grid container">
        &lt;div class="column">
            &lt;h2 class="ui teal image header">
                &lt;img src="/images/favicon.png" class="image"/>
                &lt;div class="content">
                    Cloudnweb.dev
                &lt;/div>
            &lt;/h2>
            &lt;form action="/signup" method="POST" class="ui large form">
                &lt;div class="ui stacked segment">
                    

                    &lt;div class="field">
                        &lt;div class="ui left icon input">
                            &lt;i class="user icon">&lt;/i>
                            &lt;input type="text" name="email" placeholder="Enter Email Address"/>
                        &lt;/div>
                    &lt;/div>
                    &lt;div class="field">
                        &lt;div class="ui left icon input">
                            &lt;i class="lock icon">&lt;/i>
                            &lt;input type="password" name="password" placeholder="Enter Password"/>
                        &lt;/div>
                    &lt;/div>
                    &lt;input type="submit" class="ui fluid large teal submit button" value="Sign Up">                &lt;/div>
            &lt;/form>
           
        &lt;/div>
    &lt;/div></code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p><strong>home.handlebars </strong>should look like</p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>&lt;div class="ui small menu">
  &lt;a class="active item">
    Home
  &lt;/a>
  &lt;div class="right menu">
    &lt;div class="item">
      &lt;h4>{user.email}&lt;/h4>
    &lt;/div>
    &lt;div class="item">
        &lt;a href="/logout" class="ui primary button">Log Out&lt;/a>
    &lt;/div>
  &lt;/div>
&lt;/div></code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Finally,  add the following code in the <strong>app.js</strong></p>
<!-- /wp:paragraph -->

<!-- wp:code -->
<pre class="wp-block-code"><code>const express = require('express');
const exphbs = require('express-handlebars');
const mongoose = require('mongoose');
const app = express();
const passport = require('passport');
const flash = require('connect-flash');
const morgan = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const session = require('express-session');


require('dotenv').config();

app.engine('handlebars',exphbs({defaultLayout : 'main'}));
app.set('view engine','handlebars');

app.use(morgan('dev'));
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json())


const MONGODB_URI = process.env.MONGODB_URL;

mongoose.connect(MONGODB_URI,{ useNewUrlParser : true });

var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
    console.log('connected');
});

app.use(session({secret : 'ilearnnodejs'}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());

require('./config/passport')(passport);
require('./routes/index')(app,passport);

const PORT = process.env.PORT;

app.listen(PORT,() => {
    console.log(`app is listening to port ${PORT}`);
})</code></pre>
<!-- /wp:code -->

<!-- wp:paragraph -->
<p>Now, we can run the application in command as <strong>node app.js</strong></p>
<!-- /wp:paragraph -->

<!-- wp:paragraph -->
<p>we will see how to login using  passport authentication in part 2 : <a href="https://cloudnweb.dev/2019/04/node-authentication-using-passport-js-part-2/">https://cloudnweb.dev/2019/04/node-authentication-using-passport-js-part-2/</a></p>
<!-- /wp:paragraph -->