Node.js, Express.js, Mongoose.js and Passport.js Authentication

by Didin J. on Mar 06, 2017 Node.js, Express.js, Mongoose.js and Passport.js Authentication

How to create user authentication or login using Node.js, Express.js, Mongoose.js and Passport.js with simple application example.

This tutorial is how to create user authentication or login in the Node.js application with the combination of Express.js, Mongoose.js, and Passport.js. All of those libraries, modules, and dependencies are ready to use in the Node environment. And we will use Jade as a template engine with Bootstrap 3 as a responsive CSS framework for making styling fast and easy. As usual, let's jump to the tutorial.

Jumps to the steps:

Passport.js is authentication (login) or security middleware for the Node.js environment.

It's a flexible and works great with Express.js and also supported OAuth authentication, Facebook, Twitter, etc strategies. This time we will combine the authentication or login in the Node.js/Express.js web application. Authentication or login mechanism will fully be handled by Passport.js. The flow for this Node.js, Express.js, Mongoose.js, and Passport.js tutorial will be like this.

Node Express Mongoose Passport js - Flow

Before jump the main steps, make sure you have installed Node.js (recommended version) and MongoDB server. The rest frameworks, modules, and libraries will be installed in the Node.js environment.


Create Express.js web application

We assume that you already installed all required tools like Node.js and Express.js application generator. Open terminal or cmd then go to the projects folder and run this command.

express node-passport-auth

Different from previous Node.js tutorial that now we are not using '--ejs' prefix because now, we will use 'jade' as template engine that comes as default Express.js application generation. Go to the newly created folder then install the NPM module.

cd node-passport-auth && npm install

And here is generated application project structure.

Node.js, Express.js, Mongoose.js and Passport.js Authentication - Project Folder

Now, you can run the application to make sure everything working properly. You can use one of the commands below.

nodemon

or

npm start

If you see this page, that would be easy to continue to the next steps.

Node.js, Express.js, Mongoose.js and Passport.js Authentication - Express homepage


Install Mongoose.js and Passport.js modules and dependencies

Now, we have to add database ORM/ODM for connection Node.js application with MongoDB database. For that, type this command after you stop the application.

npm install mongoose --save

For Passport.js we have to run this command.

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

We have to install Express-Session too for storing authentication token in cookies.

npm install express-session --save

Open and edit app.js from the root of the project folder. Add Mongoose.js to 'require' and call connection to MongoDB.

var mongoose = require('mongoose');
mongoose.Promise = global.Promise;

mongoose.connect('mongodb://localhost/node-auth')
  .then(() =>  console.log('connection succesful'))
  .catch((err) => console.error(err));

Add require for passport and passport-local.

var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;

In 'app.use' section add these lines for initializing passport and express-session.

app.use(require('express-session')({
    secret: 'keyboard cat',
    resave: false,
    saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());

Now, add passport configuration.

var User = require('./models/user');
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

Now run again the application, but don't forget to run MongoDB server in another terminal tab. If you run again your application and see the message below, then your application mongoose configuration is ok.

[nodemon] 1.11.0
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `node ./bin/www`
connection succesful

 


Create Mongoose.js User Model

This time to create models for authentication requirement. Create a new folder in the root of the project folder then add the file for User Model.

mkdir models
touch models/User.js

Open and edit models/User.js then add these lines of codes.

var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var passportLocalMongoose = require('passport-local-mongoose');

var UserSchema = new Schema({
    username: String,
    password: String
});

UserSchema.plugin(passportLocalMongoose);

module.exports = mongoose.model('User', UserSchema);

 


Create Express Controller for Authentication or Login

To control access from views to models and vice-versa, we will create Controller for authentication or login. This is just implementing a basic MVC pattern. Create controllers folder then create a controller file on the root of the project folder.

mkdir controllers
touch controllers/AuthController.js

Open and edit AuthController.js then add all these lines of codes.

var mongoose = require("mongoose");
var passport = require("passport");
var User = require("../models/User");

var userController = {};

// Restrict access to root page
userController.home = function(req, res) {
  res.render('index', { user : req.user });
};

// Go to registration page
userController.register = function(req, res) {
  res.render('register');
};

// Post registration
userController.doRegister = function(req, res) {
  User.register(new User({ username : req.body.username, name: req.body.name }), req.body.password, function(err, user) {
    if (err) {
      return res.render('register', { user : user });
    }

    passport.authenticate('local')(req, res, function () {
      res.redirect('/');
    });
  });
};

// Go to login page
userController.login = function(req, res) {
  res.render('login');
};

// Post login
userController.doLogin = function(req, res) {
  passport.authenticate('local')(req, res, function () {
    res.redirect('/');
  });
};

// logout
userController.logout = function(req, res) {
  req.logout();
  res.redirect('/');
};

module.exports = userController;

Create Express Routes

We need to create routes for the authentication mechanism. Open and edit routes/index.js then add this all lines of codes.

var express = require('express');
var router = express.Router();
var auth = require("../controllers/AuthController.js");

// restrict index for logged in user only
router.get('/', auth.home);

// route to register page
router.get('/register', auth.register);

// route for register action
router.post('/register', auth.doRegister);

// route to login page
router.get('/login', auth.login);

// route for login action
router.post('/login', auth.doLogin);

// route for logout action
router.get('/logout', auth.logout);

module.exports = router;

 


Create Express Views

Now is the time for creating user interface or views. Open and edit views/layout.jade then add bootstrap for styling view via CDN.

doctype html
html
  head
    title= title
    link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css', integrity='sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u', crossorigin='anonymous')
    link(rel='stylesheet', href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css', integrity='sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp', crossorigin='anonymous')
    link(rel='stylesheet', href='/stylesheets/style.css')
  body
    nav.navbar.navbar-default
      div.container-fluid
        div.navbar-header
          button.navbar-toggle.collapsed(type='button', data-toggle='collapse', data-target='#bs-example-navbar-collapse-1', aria-expanded='false')
            span.sr-only Toggle navigation
            span.icon-bar
            span.icon-bar
            span.icon-bar
          a.navbar-brand(href='#') Node.js Auth
        div.collapse.navbar-collapse(id='bs-example-navbar-collapse-1')
          ul.nav.navbar-nav.navbar-right
            if (!user)
              li
                a(href='/login') Login
              li
                a(href='/register') Register
            if (user)
              li
                a Welcome #{user.name}
              li
                a(href='/logout') Logout

    div.container
      div.content
        block content

    script(src='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js', integrity='sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa', crossorigin='anonymous')


Open and edit views/index.jade then replace all codes with this.

extends layout

block content
  h1 Node.js, Express.js, Mongoose.js and Passport.js
  p User Authentication Example


Create new files for login and register form.

touch views/login.jade
touch views/register.jade

Open and edit views/login.jade then add these lines of codes.

extends layout

extends layout

block content
  .container
    form.form-signin(role='form', action='/login', method='post')
      h2.form-signin-heading Please sign in
      label.sr-only(for='inputEmail')
      input.form-control(type='text', name='username', id='inputEmail', placeholder='Username', required, autofocus)
      input.form-control(type='password', name='password', id='inputPassword', placeholder='Password')
      button.btn.btn-lg.btn-primary.btn-block(type='submit') LOGIN


Open and edit views/register.jade then add these lines of codes.

extends layout

block content
  .container
    form.form-signin(role='form', action="/register",method="post", style='max-width: 300px;')
      h2.form-signin-heading Sign Up here
      input.form-control(type='text', name="name", placeholder='Your Name')
      input.form-control(type='text', name="username", placeholder='Your Username')
      input.form-control(type='password', name="password", placeholder='Your Password')
      button.btn.btn-lg.btn-primary.btn-block(type='submit') Sign Up

Next, we have to do a little styling for these views. Open and edit public/stylesheets/style.css then replace all code with this.

body {
  background-color: #eee;
}

.form-signin {
  max-width: 330px;
  padding: 15px;
  margin: 0 auto;
}
.form-signin .form-signin-heading,
.form-signin .checkbox {
  margin-bottom: 10px;
}
.form-signin .checkbox {
  font-weight: normal;
}
.form-signin .form-control {
  position: relative;
  height: auto;
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
  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;
}


Run and Test the Node, Express, Mongoose Authentication or Login Application

Finally, we have to try and run the application to see if all functionality is working fine.

nodemon

Open a browser and point to 'localhost:3000'. You should see this page on the browser.

Node.js, Express.js, Mongoose.js and Passport.js Authentication - Final View

You can start register then it will automatically log in.

Full source code on Github.

This tutorial uses basic Node.js and Express.js with help of Mongoose.js, Passport.js, and Bootstrap. Feel free to give us input or suggestion in the comment below.

That just the basic. If you need more deep learning about MEAN Stack, Angular, and Node.js, you can take the following cheap course:

Thanks.

Loading…