HI WELCOME TO SIRIS
Showing posts with label node.js. Show all posts
Showing posts with label node.js. Show all posts

Express Middleware Tutorial Example From Scratch

Leave a Comment
Express Middleware Tutorial Example From Scratch is today’s leading topic.  Express works like when we hit the request on the server; it must return a  response of a webpage like HTML or PHP or send a JSONresponse to the API call. Express is a very lightweight web framework. It comes with some features like Middleware. Middleware function is a function that has access to the request object (req), the response object (res), and the next middleware function in the application’s request-response cycle. The next middleware function is commonly denoted by a variable named next.
Middleware function can perform the following tasks.
  • Can execute any code.
  • Can make changes to the request and the response objects.
  • Can end the request-response cycle.
  • Can call the next middleware function in the stack.
If the current middleware function does not end the request-response cycle, it must call next() to pass control to the next middleware function. Otherwise, the request will be left hanging, and you will be stuck on the particular webpage and just loading and loading and so on.

Express Middleware Tutorial

If you are building Node js Express Web Application, then you have already used an express middleware. I will give you an example.
// For serving static files

app.use(express.static('public'));

// For parses incoming post request data

app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
As we have discussed earlier, it has next() function is available. If I want to log anything for each incoming request, then I need to write following code.
const logger = function (req, res, next) {
  console.log('Middleware is used first time');
  next();
}
Similarly, there is one Node package called Morgan which is doing the same thing. Log all the request in the console. In actual Node js application, we can use the middleware like following.
var express = require('express')
var app = express()

const logger = function (req, res, next) {
  console.log('caught intrusion');
  next();
}

app.use(logger);

app.get('/', function (req, res) {
  res.send('Express middleware tutorial');
});

app.listen(3000);

Authentication Example

If we have to check whether the user has logged in or not for the current route or try to access authenticated route, then we can write the following tutorial.
router.get('/', isLoggedIn, function(req, res){
   res.render('pages/index');
});

function isLoggedIn(req, res, next){
    if(req.isAuthenticated()){
        next();
    }
    else{
        res.redirect("/users/login");
    }
}
In above example is also called “Route Middleware.” It checks the request to see if the user is authenticated or not. Based on the function response, it will redirect the user accordingly.

Configurable middleware

If you need your middleware to be configurable, export a function which accepts an options object or other parameters, which, then returns the middleware implementation based on the input parameters.
// First.middleware.js

module.exports = function(options) {
  return function(req, res, next) {
    // Implement the middleware function based on the options object
    next();
}
Now, use this middleware in our server.js file or name it as you want.
// server.js

var Fm = require('./First.middleware.js');

app.use(Fm({ option1: 'App', option2: 'Dividend' }));

Types of  Express Middleware

There are mainly five types of middlewares.

Application-level middleware

Bind application-level middleware to an instance of the app object by using the app.use().
This example shows a middleware function with no mount path. Every time user sends a request, the middleware function always runs.
var express = require('express')
var app = express()

const logger = function (req, res, next) {
  console.log('caught intrusion');
  next();
}

app.use(logger);

app.get('/', function (req, res) {
  res.send('Express middleware tutorial');
});

Router-level middleware

Router-level middleware bound to an instance of express.router().
const router = express.Router();
Load router-level middleware by using the router.use() function.
const app = express();
const router = express.Router();

router.use(function (req, res, next) {  
console.log('Time:', Date.now());
  next();
});

Error-handling middleware

Define error-handling middleware functions with four arguments instead of three, specifically with the signature (err, req, res, next).
app.use(function (err, req, res, next) {
  console.error(err.stack);
  res.status(500).send('Whoops! Something went wrong');
});

Built-in middleware

Express has the following built-in middleware functions:

Third-party middleware

Install the Node.js package for the required functionality, then load it in your application at the application level or the router level. We have already seen the body-parser middleware, which is third-party middleware.

Finally, our Express Middleware Tutorial is over.

Simple Nodejs Authentication System Using Passport

Leave a Comment
Simple Nodejs Authentication System Using Passport is today’s leading topic. In this tutorial, you will learn how to use a passport.js to authenticate the user. So, what is Passport.jsPassport.js is a simple, unobtrusive Node.js authentication middleware for Node.js.Passport.js can be used in any Express.js-based web application. So we will use the Node.js as a platform, Express as a web framework, MongoDBas a database and Passport.js as a Middleware library for the web application.

Nodejs Authentication System Using Passport

We will build an authentication system step by step, and it is going to be a long ride. So stay tuned.
Note: If any step you will find any errors then please go to my Github code. A link is at the below of the post.

Step 1: Install the NPM dependencies

First, we need to install all the required dependencies for this project. So create one file called package.json. We can create this file using the terminal. Go to the root of the project and hit the following command.
npm init
So answer the all the questions, and it will create a file.
Next, you will write some of its dependencies as follow.
{
  "name": "expresslogin",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "nodemon ./server.js --exec babel-node -e js"
  },
  "dependencies": {
    "bcryptjs": "*",
    "body-parser": "*",
    "connect-flash": "*",
    "cookie-parser": "*",
    "express": "*",
    "ejs": "*",
    "express-messages": "*",
    "express-session": "*",
    "express-validator": "*",
    "mongodb": "*",
    "mongoose": "*",
    "nodemon": "*",
    "passport": "*",
    "passport-http": "*",
    "passport-local": "*"
  },
  "devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1"
  },
  "author": "Sireesh Kantamaneni",
  "license": "ISC"
}
Here I have to install dependencies and dev dependencies. Copy this two objects dependencies and dev dependencies in your project and then hit the following command.
npm install
Also, we have installed babel-cli because it can transform our ES6 code into ES5 and run the Node.js code on the server. Create one more file called .babelrc.
{
  "presets": [
    "es2015", "stage-0"
  ]
}

Step 2: Make server.js file and start the node server

In root directory, create one file called server.js.
import express from 'express';
import path from 'path';
import cookeParser from 'cookie-parser';
import bodyParser from 'body-parser';
import ejs from 'ejs';
import expressValidator from 'express-validator';
import flash from 'connect-flash';
import session from 'express-session';
import passport from 'passport';
const LocalStrategy = require('passport-local').Strategy;
import mongoose from 'mongoose';

const app = express();
const PORT = 3000;

mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost/passport', {
  useMongoClient: true
});

app.get('/', (req, res) => {
  res.send('Node and express are properly running');
});

app.listen(PORT, function(){
  console.log('Server is running on',PORT);
});
Now,  go to the terminal and hit the following command.
npm start
It will start the server, and at the port 3000, our application is running. So go to the http://localhost:3000
Node and express are properly running.”
Next, we need to set the view engine and middlewares for our application.

// app.js

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(cookeParser());

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

app.use(session({ secret: 'keyboard cat', resave: false, saveUninitialized: true, }));

app.use(expressValidator());

app.use(flash());

app.use(function(req, res, next){
  res.locals.success_message = req.flash('success_message');
  res.locals.error_message = req.flash('error_message');
  res.locals.error = req.flash('error');
  next();
});
We have set the view engine to ejs and set the express validatorsessions and flash message middlewares.
Also, we have initialized the passport library.

Step 3: Making required directories

In the root folder, make one directory called views and inside that directory, create one directory called pages.
Inside pages directory, make following two files.
  1. index.ejs
  2. users.ejs
Also, we need to make one more folder inside the views directory called partials. This folder contains a header, footer and sidebar files. 
Right now, I am just creating a header.ejs file.
<!-- header.ejs -->

<nav class="navbar navbar-default" role="navigation">
  <div class="container-fluid">
      <div class="navbar-header">
          <a class="navbar-brand" href="#">
              Express Auth App
          </a>
          <ul class="nav navbar-nav">
              <li><a href="/">Home</a></li>
              <li><a href="/users/register">Register</a></li>
              <li><a href="/users/login">Login</a></li>
          </ul>
     </div>
   </div>
</nav>
Next, make one directory in the root called, routes and inside that, create two files.
  1. index.js
  2. users.js
Write the following code inside the index.js
// routes > index.js

import express from 'express';
let router =  express.Router();

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

export default router;
Also, write the following code inside the users.js file.
// routes > users.js

import express from 'express';
let router =  express.Router();

router.get('/', function(req, res){
  res.render('pages/users');
});
router.get('/register', function(req, res){
  res.render('pages/register');
});

export default router;
Now, import this files into the server.js file. I am displaying final server.js file code.
// server.js

import express from 'express';
import path from 'path';
import cookeParser from 'cookie-parser';
import bodyParser from 'body-parser';
import ejs from 'ejs';
import expressValidator from 'express-validator';
import flash from 'connect-flash';
import session from 'express-session';
import passport from 'passport';
const LocalStrategy = require('passport-local').Strategy;
import mongoose from 'mongoose';
import index from './routes/index';
import users from './routes/users';

mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost/CRMDB', {
  useMongoClient: true
});
let db = mongoose.connect;

const app = express();
const PORT = 3000;

app.use(express.static(__dirname + '/public'));

app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookeParser());

app.use(session({
 secret: 'keyboard cat',
 resave: false,
 saveUninitialized: true,
}));

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

app.use(expressValidator());

app.use(flash());

app.use(function(req, res, next){
 res.locals.success_message = req.flash('success_message');
 res.locals.error_message = req.flash('error_message');
 res.locals.error = req.flash('error');
 res.locals.user = req.user || null;
 next();
});

app.use('/', index);
app.use('/users', users);

app.listen(PORT, function(){
 console.log('Server is running on',PORT);
});

Step 4: Create pages of login and register

First, we need to include the bootstrap css framework to design the web pages.
Now, include the header.ejs part in the index.ejs file.
<!-- index.ejs -->

<html>
 <head>
   <title>INDEX</title>
   <link href="/css/bootstrap.min.css" rel="stylesheet" type="text/css">
 </head>
 <body>
  <div class="container">
        <% include ../partials/header %>
    Home Page
   </div>
</body>
</html>
Now, create a register.ejs file inside views  >>  pages folder.
<!-- register.ejs -->

<html>
  <head>
    <title>Register</title>
    <link href="/css/bootstrap.min.css" rel="stylesheet" type="text/css">
  </head>
  <body>
    <div class="container">
      <% include ../partials/header %>
      <div class="panel panel-primary">
        <div class="panel-heading">
          Register The User
        </div>
        <div class="panel-body">
          <form method="post" action="/register">
            <div class="form-group">
              <label class="col-md-4">Name</label>
              <input type="text" class="form-control" name="name"/>
            </div>
            <div class="form-group">
              <label class="col-md-4">Email</label>
              <input type="text" class="form-control" name="email"/>
              </div>
              <div class="form-group">
                <label class="col-md-4">Password</label>
                <input type="password" class="form-control" name="password"/>
              </div>
              <div class="form-group">
                <label class="col-md-4">Confirm Password</label>
                <input type="password" class="form-control" name="cfm_pwd"/>
              </div>
              <div class="form-group">
                <button type="submit" class="btn btn-primary">Add User</button>
              </div>
          </form>
        </div>
      </div>
    </div>
  </body>
</html>

Step 5: Server side validation.

In the routes >> users.js file, paste the following code.
// users.js

router.post('/register', function(req, res){
  let name = req.body.name;
  let email = req.body.email;
  let password = req.body.password;
  let cfm_pwd = req.body.cfm_pwd;

  req.checkBody('name', 'Name is required').notEmpty();
  req.checkBody('email', 'Email is required').notEmpty();
  req.checkBody('email', 'Please enter a valid email').isEmail();
  req.checkBody('password', 'Password is required').notEmpty();
  req.checkBody('cfm_pwd', 'Confirm Password is required').notEmpty();
  req.checkBody('cfm_pwd', 'Confirm Password Must Matches With Password').equals('req.body.password');

  let errors = req.validationErrors();
  if(errors){
    res.render('pages/register',{errors: errors});
  }
  else{
    console.log('Success');
  }
});
Now, we have put the server side validation, so we need to display the errors, so what we have done is put the error and success messages inside the header.ejs file.
<%if (success_message != '') { %>
 <div class="alert alert-success">
  <%= success_message %>
 </div>
<% } %>
<%if (error_message != '') { %>
 <div class="alert alert-danger">
  <%= error_message %>
 </div>
<% } %>
<%if (error != '') { %>
 <div class="alert alert-danger">
  <%= error %>
 </div>
<% } %>

Step 6: Save the User in the database.

Make one folder in the project root called models and inside make one file called User.js
// User.js

import mongoose from 'mongoose';
import bcrypt from 'bcryptjs';

let UserSchema = mongoose.Schema({
  name: {
    type: String,
    index: true
  },
  email: {
    type: String
  },
  password: {
    type: String
  }
});

export const User = mongoose.model('User', UserSchema);

export const createUser = (newUser, callback) => {
  bcrypt.genSalt(10, function(err, salt) {
    bcrypt.hash(newUser.password, salt, function(err, hash) {
        newUser.password = hash;
        newUser.save(callback);
    });
  });
}
Now, import this User model into the routes  >> users.js file.
So final file looks like this.
import express from 'express';
import { User, createUser } from '../models/User';
let router =  express.Router();

router.get('/', function(req, res){
  res.render('pages/users');
});
router.get('/register', function(req, res){
  res.render('pages/register');
});
router.post('/register', function(req, res){
  let name = req.body.name;
  let email = req.body.email;
  let password = req.body.password;
  let cfm_pwd = req.body.cfm_pwd;

  req.checkBody('name', 'Name is required').notEmpty();
  req.checkBody('email', 'Email is required').notEmpty();
  req.checkBody('email', 'Please enter a valid email').isEmail();
  req.checkBody('password', 'Password is required').notEmpty();
  req.checkBody('cfm_pwd', 'Confirm Password is required').notEmpty();
  req.checkBody('cfm_pwd', 'Confirm Password Must Matches With Password').equals(password);

  let errors = req.validationErrors();
  if(errors)
  {
    res.render('pages/register',{errors: errors});
  }
  else
  {
    let user = new User({
      name: name,
      email: email,
      password: password
    });
    createUser(user, function(err, user){
        if(err) throw err;
        else console.log(user);
    });
    req.flash('success_message','You have registered, Now please login');
    res.redirect('login');
  }
});

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

router.post('/login', function(req, res){
  res.render('pages/login');
});

export default router;
Also, we need to make a login page in the views >> pages folder.
<!-- login.ejs -->

<!doctype html>
  <head>
    <title>Login User</title>
    <link href="/css/bootstrap.min.css" rel="stylesheet" type="text/css">
  </head>
  <body>
    <div class="container">
      <% include ../partials/header %>
      <div class="panel panel-primary">
        <div class="panel-heading">
          Login User
        </div>
        <div class="panel-body">
          <form method="post" action="/users/login">
            <div class="form-group">
              <label class="col-md-4">Email</label>
              <input type="text" class="form-control" name="email"/>
              </div>
              <div class="form-group">
                <label class="col-md-4">Password</label>
                <input type="password" class="form-control" name="password"/>
              </div>
              <div class="form-group">
                <button type="submit" class="btn btn-primary">Login</button>
              </div>
          </form>
        </div>
      </div>
    </div>
  </body>
</html>
Change the header navigation also.
<!-- header.ejs -->

<nav class="navbar navbar-default" role="navigation">
  <div class="container-fluid">
      <div class="navbar-header">
          <a class="navbar-brand" href="#">
              Express Auth App
          </a>
          <ul class="nav navbar-nav">
              <li><a href="/">Home</a></li>
              <li><a href="/users/register">Register</a></li>
              <li><a href="/users/login">Login</a></li>
          </ul>
      </div>
    </div>
    </nav>
If everything is okay, then you can see the user has been created, saved in the MongoDB database and you can also see the user in the console.

Step 7: Write the logic for Login.

Next step would be to write the passport authenticate middleware inside the post route of the login and the login.
// routes  >>  users.js

router.post('/login', passport.authenticate('local', {
    failureRedirect: '/users/login', failureFlash: true
    }), 
    function(req, res){
        req.flash('success_message', 'You are now Logged in!!');
    res.redirect('/');
    }
);
Now, we need to use local passport strategy. So write the code inside the users.js file.
// routes >> users.js

passport.use(new LocalStrategy({
 usernameField: 'email',
 passwordField: 'password',
 passReqToCallback : true
},
 function(req, email, password, done) {
   getUserByEmail(email, function(err, user) {
   if (err) { return done(err); }
   if (!user) {
    return done(null, false, req.flash('error_message', 'No email is found'));
   }
   comparePassword(password, user.password, function(err, isMatch) {
    if (err) { return done(err); }
    if(isMatch){
    return done(null, user, req.flash('success_message', 'You have successfully logged in!!'));
    }
    else{
        return done(null, false, req.flash('error_message', 'Incorrect Password'));   }
    });
   });
  }
));

passport.serializeUser(function(user, done) {
  done(null, user._id);
});

passport.deserializeUser(function(id, done) {
  getUserById(id, function(err, user) {
    done(err, user);
  });
});
Now, the whole file will look like this.
// users.js

import express from 'express';
import { User, createUser, comparePassword, getUserByEmail, getUserById } from '../models/User';
import passport from 'passport';

let LocalStrategy = require('passport-local').Strategy;
let router =  express.Router();

router.get('/', function(req, res){
    res.render('pages/users');
});
router.get('/register', function(req, res){
   res.render('pages/register');
});
router.post('/register', function(req, res){
   let name = req.body.name;
    let email = req.body.email;
    let password = req.body.password;
    let cfm_pwd = req.body.cfm_pwd;

    req.checkBody('name', 'Name is required').notEmpty();
    req.checkBody('email', 'Email is required').notEmpty();
    req.checkBody('email', 'Please enter a valid email').isEmail();
    req.checkBody('password', 'Password is required').notEmpty();
    req.checkBody('cfm_pwd', 'Confirm Password is required').notEmpty();
    req.checkBody('cfm_pwd', 'Confirm Password Must Matches With Password').equals(password);

    let errors = req.validationErrors();
    if(errors)
    {
        res.render('pages/register',{errors: errors});
    }
    else
    {
        let user = new User({
        name: name,
        email: email,
        password: password
        });
        createUser(user, function(err, user){
            if(err) throw err;
            else console.log(user);
        });
        req.flash('success_message','You have registered, Now please login');
        res.redirect('login');
    }
});

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

passport.use(new LocalStrategy({
    usernameField: 'email',
    passwordField: 'password',
    passReqToCallback : true
},
    function(req, email, password, done) {
     getUserByEmail(email, function(err, user) {
        if (err) { return done(err); }
       if (!user) {
            return done(null, false, req.flash('error_message', 'No email is found'));
       }
       comparePassword(password, user.password, function(err, isMatch) {
         if (err) { return done(err); }
         if(isMatch){
           return done(null, user, req.flash('success_message', 'You have successfully logged in!!'));
         }
         else{
           return done(null, false, req.flash('error_message', 'Incorrect Password'));
        }
     });
     });
  }
));

passport.serializeUser(function(user, done) {
   done(null, user._id);
});

passport.deserializeUser(function(id, done) {
   getUserById(id, function(err, user) {
        done(err, user);
   });
});

router.post('/login', passport.authenticate('local', {
    failureRedirect: '/users/login', failureFlash: true
    }), 
    function(req, res){
        req.flash('success_message', 'You are now Logged in!!');
    res.redirect('/');
    }
);

router.get('/logout', function(req, res){
    req.logout();
    req.flash('success_message', 'You are logged out');
    res.redirect('/users/login');
});

export default router;
Also, we have imported models  >>  User.js.
// models  >>  User.js

import mongoose from 'mongoose';
import bcrypt from 'bcryptjs';
import passport from 'passport';

let UserSchema = mongoose.Schema({
    name:{
    type: String,
    index: true
   },
   email:{
    type: String
   },
   password:{
    type: String
   }
});

export const User = mongoose.model('User', UserSchema);

export const createUser = (newUser, callback) => {
 bcrypt.genSalt(10, function(err, salt) {
    bcrypt.hash(newUser.password, salt, function(err, hash) {
        newUser.password = hash;
        newUser.save(callback);
    });
   });
}

export const getUserByEmail = (email, callback) => {
  let Obj = {email: email}
  User.findOne(Obj, callback);
}

export const comparePassword = (password, hash, callback) => {
 bcrypt.compare(password, hash, function(err, isMatch){
    if(err) throw err;
    callback(null, isMatch);
 });
}

export const getUserById = (id, callback) => {
   User.findById(id, callback);
}
Now, we need to write isLoggedIn middleware in the routes  >>  index.js file.
import express from 'express';
let router =  express.Router();

router.get('/', isLoggedIn, function(req, res){
   res.render('pages/index');
});

function isLoggedIn(req, res, next){
    if(req.isAuthenticated()){
        next();
    }
    else{
        res.redirect("/users/login");
    }
}

export default router;
Also, our header.ejs file looks like this.
<!-- header.ejs -->

<header>
 <nav class="navbar navbar-default" role="navigation">
      <div class="container-fluid">
    <div class="navbar-header">
        <a class="navbar-brand" href="#">
           Express Auth App
        </a>
        <ul class="nav navbar-nav">
         <% if(user){ %>
          <li><a href="/">Home</a></li>
          <li><a href="/users/logout">Logout</a></li>
             <% } else{ %>  
           <li><a href="/users/register">Register</a></li>
           <li><a href="/users/login">Login</a></li>
          <% } %>
             </ul>
           </div>
    </div>
    </nav>
</header>
<%if (success_message != '') { %>
 <div class="alert alert-success">
    <%= success_message %>
 </div>
<% } %>
<%if (error_message != '') { %>
  <div class="alert alert-danger">
    <%= error_message %>
  </div>
<% } %>
<%if (error != '') { %>
 <div class="alert alert-danger">
    <%= error %>
 </div>
<% } %>

Github Code

If you still find any error then please go to my Github Code.

Our tutorial on Nodejs Authentication System Using Passport is over.