Building Web Applications Using Node.js - Part Six

Before reading this article, I would recommend that you read my previous articles.
In my previous articles series, I explained the following:
  • How to start working with Node.js Web application.
  • How to initialize a Node.js project.
  • About Package.JSON.
  • Express Framework.
  • How to use "npm start" command.
  • Using HTML Templates.
  • Bower.
  • Templating Engine.
  • Navigation.
  • Routing.
  • Rendering.
  • Fetching data from MongoDB
  • User Registration
Introduction

In this article, we will learn how to authenticate a user using Node.js. So, in this article, I will create a login page and we will authenticate the users using MongoDB when they login; and, once logged in successfully, we will redirect them to the profile page. So, we will do all this using passport.
 
What is passport? 

Passport is an authentication middleware for Node.js. Extremely flexible and modular, passport can be unobtrusively dropped into any express-based web application. A comprehensive set of strategies support authentication using a username and password, as well as social logins like Facebook, Google, Twitter, LinkedIn, etc. This is fairly standard in Node.js and Express, which is used by most of the people when dealing with login, using Node.js.
 
Let's start step by step.
 
In my last article (Building Web Application Using Node.js - part 5 ), I explained how to work with registration page. We created a registration page and registered ourselves. Same as with registration page, I am going to create a login page. Let's do this step by step.
 
Creating Login Form

Step 1

First of all, I am going to create a routing file with the name, "loginRoute.js" in "/src/routes" folder.



Step 2

Now, inside loginRoute.js file, I am going to write the following code.
  1. var express=require('express');  
  2. var loginRouter=express.Router();  
  3. var l_router=function(navMenu){  
  4.     loginRouter.route("/")  
  5.         .get(function(req,res){  
  6.                 res.render('login', {  
  7.                     title:'Login',  
  8.                     menu:navMenu,  
  9.                     message:''  
  10.                 });  
  11.         });  
  12.         return loginRouter;  
  13. }     
  14. module.exports=l_router;  
Step 3

After that, I am updating routes in app.js file, by writing the following code.
  1. var loginRouter=require('./src/routes/loginRoute')(navMenu);  
  2.   
  3. app.use('/login',loginRouter);  
Step 4

Now, I am creating a View for Login page. For that, I am creating a file inside views folder, named as "login.ejs".

 
 
Step 5

For login.ejs, I am writing the following code.
  1.  <!-- Page Heading -->  
  2. <div class="row">  
  3.     <div class="col-lg-12">  
  4.         <h1 class="page-header">Login</h1>  
  5.     </div>  
  6. </div>  
  7. <!-- /.row -->  
  8. <form class="form-horizontal" action="/login" method="post">  
  9.     <fieldset>  
  10.         <div class="form-group">  
  11.             <label class="col-md-1 control-label" for="Email">Email</label>    
  12.             <div class="col-md-4">  
  13.                 <input id="Email" name="Email" type="email" placeholder="Email" class="form-control input-md" required>  
  14.             </div>  
  15.         </div>  
  16.         <div class="form-group">  
  17.             <label class="col-md-1 control-label" for="Password">Password</label>    
  18.             <div class="col-md-4">  
  19.                 <input id="Password" name="Password" type="password" placeholder="Password" class="form-control input-md" required>  
  20.             </div>  
  21.         </div>  
  22.         <div class="form-group">  
  23.             <div class="col-md-4 col-md-offset-1">  
  24.                 <input type="submit" id="Submit" class="btn btn-primary" value="Login" />  
  25.             </div>  
  26.         </div>  
  27.     </fieldset>  
  28. </form>  
  29. <h3><%=message%></h3>  
Step 6

Now, if we start this project, then our output will be like in the below image.


As I have told you, we will use passport authentication, we have to use a couple of middlewares for simple authentication. 
 
Passport Middleware

If we are using simple passport authentication, we need a couple of pieces of middleware so that the passport can perform its process. For passport authentication, we will use the following functions.
  • passport.initialize()
    This is used to initialize the passport. 

  • passport.session()
    This function provides persistent login. As we are creating login page, so of course, our application should use persistent login session. This function sits on the top of the Express session, so we have to install express.session as well, for our web application. 
For doing that, we must be using the following middleware. 
  • cookie-parser - used to populate request cookies. If authentication succeeds, a session will be established and maintained via a cookie set in the user's browser.

  • express-session - used to store the user information and other information.

  • passport - the main middleware if we are performing passport authentication.
How to use passport?

To understand how to use passport, you have to follow these steps.

Step 1

First of all, install cookie-parser, express-session, passport middleware, using the following commands.

 
Now, if you see your package.json file, you will get the dependencies for all, as shown in the following figure.

 
 
Step 2

Now, add the references of all the files in app.js. You can use the following code for that. 
  1. var cookieParser=require('cookie-parser');  
  2. var passport=require('passport');  
  3. var session=require('express-session');  
Step 3

Now, to use all middleware, you have to tell the application that we will use these things. Before telling the application about it, I am just creating a separate file for this passport information. So, I am creating one folder named "configuration" inside "src" directory and then, I am creating a file named passport.js

 
 
Step 4

Now, write the following code in passport.js
  1. var passport=require('passport');  
  2.   
  3. module.exports=function(app){  
  4.      app.use(passport.initialize());  
  5.      app.use(passport.session());  
  6. }  
Step 5

As we know, in a web application, the username and password (means credentials) is used to authenticate a user, which will only be transmitted when a user requests login. If authentication succeeds, then a session is established and that is maintained via a cookie set in the user's browser.  
 
But, each subsequent request doesn't contain credentials, rather, it contains the unique cookie that identifies the session. In order to support login sessions, Passport serializes and de-serializes user instances to and from the session.
 
So, I am writing the following code in passport.js file for serialization and deserializion of user instance.
  1. var passport=require('passport');  
  2.   
  3. module.exports=function(app){  
  4.     app.use(passport.initialize());  
  5.     app.use(passport.session());  
  6.       
  7.     passport.serializeUser(function(user, done) {  
  8.         done(null, user);  
  9.     });  
  10.       
  11.     passport.deserializeUser(function(user, done) {  
  12.         done(null, user);  
  13.     });  
  14. }  
Step 6

Now, in app.js file, I am writing the following code to tell our application that we are going to use this passport.js and sessions and cookie parser.
  1. app.use(cookieParser());  
  2. app.use(session({secret:'c-sharpcorner'}));  
  3. require('./src/configuration/passport')(app);  
Step 7

Now, to login using passport, we have to use the passport strategy.

What is passport strategy?

The passport strategy is just a way to authenticate a user. It may be via username and password or it may be via social profile login like login with Facebook, Google, Twitter, LinkedIn, GitHub etc.
 
In this article, we are just using passport-local which authenticates using username and password. So, first of all, I am going to install passport-local using the following command.

 
 
Using passport-local

To configure passport-local, use the following steps.

Step 1

First, I am again creating separate files for local-passport because in my upcoming article, I will show you how to login using Facebook, Google, Twitter and all social media sites. I am just creating a file "local.strategy.js" inside "src/configuration/strategies" folder. Folder structure is shown in the following figure.

 
 
Step 2

Now, in passport.js, just give reference for local strategy.

 
 
Step 3

Now, to implement local-passport strategy, write the following code in local.strategy.js file.
  1. var passport = require('passport'),  
  2.     LocalStrategy = require('passport-local').Strategy;  
  3. var mongodb=require('mongodb').MongoClient;  
  4. module.exports=function(){  
  5.     passport.use(new LocalStrategy({  
  6.         usernameField:'Email',  
  7.         passwordField:'Password'  
  8.     },  
  9.     function(username, password, done) {  
  10.         var url='mongodb://localhost:27017/NodeDemoWebApp';  
  11.         mongodb.connect(url,function(err,db){  
  12.             if(err){done(null,false, {message:'Invalid Credentials'});}  
  13.             var collection=db.collection('Users');  
  14.             collection.findOne({Email:username},function(err,results){  
  15.                 if(results.Password==password){  
  16.                     var user=results;  
  17.                     done(null,user);  
  18.                 }  
  19.                 else{  
  20.                     done(null,false, {message:'Invalid Credentials'});  
  21.                 }  
  22.             });  
  23.         });  
  24.     }));  
  25. };  
In the above code, I am exporting a function which takes one object usernameField and passwordField, the names of which will be the name attribute of our control, like you will see in the login.ejs file we have taken. 
  1. <input id="Email" name="Email" type="email" placeholder="Email" class="form-control input-md" required>  
  2.   
  3. <input id="Password" name="Password" type="password" placeholder="Password" class="form-control input-md" required>  
After that, I am getting all users via email and checking password. If password is done, then I am setting user as a result. Otherwise, I am setting null as a result.
 
For reading more about passport, use the following document. You will get more ideas from here- Passport Documentation
 
Step 4

Now, we will implement loginRoute.js.
  1. var express=require('express');  
  2. var passport=require('passport');  
  3. var loginRouter=express.Router();  
  4. var l_router=function(navMenu){  
  5.     loginRouter.route("/")  
  6.         .post(passport.authenticate('local',{  
  7.             failureRedirect:'/login'  
  8.         }),function(req,res){  
  9.                 res.redirect('/articles')  
  10.             }  
  11.         )  
  12.         .get(function(req,res){  
  13.                 res.render('login', {  
  14.                     title:'Login',  
  15.                     menu:navMenu,  
  16.                     message:''  
  17.                 });  
  18.         });  
  19.         return loginRouter;  
  20. }     
  21. module.exports=l_router;  
This time, when request will come, it will be sent back to the passport, using passport.authenticate method. If login is failed, then it will be redirected to the login page again, else it will be redirected to the articles page.
 
Now, run this project.

Output


After successful login, it will be redirected to the articles page.

 
Conclusion

In this article, we learned about,
  • Passport
  • Session
  • Cookie-Parser
  • Passport local strategy
  • Authentication using mongodb
What is next?

In this article, we just saw how to authenticate a user. In my next article, you will learn how to authorize a user. So, user will access a page if logged in; otherwise, they will be redirected to the login page.

<<Previous Article                                                                                                                               Next Article>>