nodejs authentication with passport js and passport local mongoose

Nodejs Authentication With Passport JS and Passport Local Mongoose

When creating a web app, a basic requirement is to make a login system with the help of which users can authenticate themselves before getting access to preserved resources or views. If you wish to create a Node app, there is an authentication middleware for Node called Passport. Passport provides authentication mechanisms with the help of a few commands. It is created for a singular purpose that is to authenticate requests. Here we will learn how Node JS authentication with Passport JS and Passport local mongoose.

Passport-Local Mongoose is a Mongoose plugin that simplifies username creation and password login with Passport. This module auto-generates salt and hash fields, you don’t require to hash the password with this crypto module, the passport-local-mongoose does this for you.

How is Salting of Password Important?

Whenever a user simply hashes their password and if there are two users in the database that have the same password, they will end up having the same hash. Now, if any one of these passwords gets hacked then the hacker can reach each account that uses the same password because users with identical passwords have the same hash fields.

Therefore, before hashing, we prepend a unique string, just something unique. So that the hash is entirely different for every salt.

Steps to Perform Authentication with Passport JS and Passport Local Mongoose 

Firstly, you need to generate an express app by installing all the needed modules.

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

 

1) You Need to Create a Directory Structure as Shown Below:

--model

----user.js

--route

----user.js

--app.js

 

2) Need to Create a Model/User.js File That Will Define the User Schema

// importing the modules 

var mongoose = require('mongoose'); 

var Schema = mongoose.Schema; 

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



var UserSchema = new Schema({   

    email: {type: String, required:true, unique:true}, 

    username : {type: String, unique: true, required:true}, 

}); 

  

// plugin for passport-local-mongoose 

UserSchema.plugin(passportLocalMongoose); 

  

// exporting the userschema 

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

 

Note: In this schema, we don’t add any field for passwords because passport-local-mongoose doesn’t need it. Also, we don’t need to add any methods to hash our password for authentication as passport-local-mongoose will do that for us.

3) Configuring Passport/Passport-Local in App.js:

Firstly in app.js, you have to initialize the passport

app.use(passport.initialize()); 

app.use(passport.session());

Now the passport maintains persistent login sessions. For persistent sessions to work in the passport, the authenticated user must remain serialized to the session and deserialized when any subsequent requests are made.

With passport-local-mongoose it remains like this:

passport.serializeUser(User.serializeUser()); 

passport.deserializeUser(User.deserializeUser());

If you are not using passport-local-mongoose with the passport then the serialized and deserialized code can be somewhat different.

Now we have to set the strategies for the passport. For passport local mongoose the code would be like:

const User = require('./models/user');
const LocalStrategy = require('passport-local').Strategy; 

passport.use(new LocalStrategy(User.authenticate()));

 

In case, you are using only the passport without a passport-local-mongoose then you will have to write some code to compare passwords and all. But using this passport-local-mongoose, only those 2 lines are enough.

4) Next Comes the Creation of the Route/User.js File:

For this, you need to import the user-schema first, along with other required modules.

// importing modules 

const express = require('express'); 

const router = express.Router(); 

    

// importing the User Schema 

const User = require('../model/user');

5) Next is the Registering Part:

For registering the code should be:

router.post('/login', function(req, res) {       

    Users=new User({email: req.body.email, username : req.body.username});   

          User.register(Users, req.body.password, function(err, user) { 

            if (err) { 

              res.json({success:false, message:"Your account could 

              not be saved. Error: ", err}) 

            }else{ 

              res.json({success: true, message: "Your account has 

               been saved"}) 

            } 

          }); 

});

In the above code, rather than defining our password in New user, we use the password with the User.Register() i.e. a passport-local-mongoose function. Now just check your database for your saved user, it will be like here:

{

    "_id" : ObjectId("5ca8b66535947f4c1e93c4f1"),

    "username" : "username you gave",

    "email" : "email you gave",

    "salt" : "4c8f6e009c4523b23553d9479e25254b266c3b7dd2dbc6d4aaace01851c9687c",

    "hash" : "337de0df58406b25499b18f54229b9dd595b70e998fd02c7866d06d2a6b25870d23650

cdda829974a46e3166e535f1aeb6bc7ef182565009b1dcf57a64205b5548f6974b77c2e3a3c6aec5360d

661efb5155e68ad0e593c0f5fab7d690c2257df4369e9d5ac7e2fc93b5b014260c6f8fbb01034b3f85ec

f5055cac0fb01a4a2288af2ce2a6563ed9b47852727749c7fe031b6b7fbb726196dbdfeeb6766d5cba6a

055f66eeacce685daef8b6c1aed0108df511c92d49150efb6473ee71c5149dd06bfb4f73cb60f9815af0

55f9fcd3ffd6fb99dce21aab021aced72881d3720f6a0975bfece4922282bb748e0412955e0afa2fb8c9

1e02fde8d8ed822bb3a55f040237cf80de0b1534de6bbafcb53f882c6eb03de4b4aa307828974eb51261

9d6231eca6edbeec4eb1436f1e45c27b9c2bfceccf3a9b42840f40c65fe499091ba6ebeb764b5d815a43

d73a888fdb58f821fbe5f7d92e20ff8d7c98e8164b4f10d5528fddbcc7737fd21b12d571355cc605eb36

f11e086e9bf860f959d0e2104a1f825d286c99d3fc6f62505d1fde8601345c699ea08dcc071e5547835c

16957d3830998a10762ebd143dc557d6a96e4b88312e1e4c51622fef3939656c992508e47ddc148696df

3152af76286d636d4814a0dc608f72cd507c617feb77cbba36c5b017492df5f28a7a3f3b7881caf6fb4a21f5f266f8e38683deb05a6de43114",

    "__v" : 0

}

You will notice here that there is no field for the password, alternatively, passport-local-mongoose generated salt and hash for you, you are not required to set salt plus and fields in your schema. Passport-local-mongoose will hold your username unique, i.e. if the username already exists it will return “UserExistsError”.

6) For Login:

Now for login,

userController.doLogin = function(req, res) { 

  if(!req.body.username){ 

    res.json({success: false, message: "Username was not given"}) 

  } else { 

    if(!req.body.password){ 

      res.json({success: false, message: "Password was not given"}) 

    }else{ 

      passport.authenticate('local', function (err, user, info) { 

         if(err){ 

           res.json({success: false, message: err}) 

         } else{ 

          if (! user) { 

            res.json({success: false, message: 'username or password incorrect'}) 

          } else{ 

            req.login(user, function(err){ 

              if(err){ 

                res.json({success: false, message: err}) 

              }else{ 

                const token = jwt.sign({userId : user._id, 

                   username:user.username}, secretkey, 

                      {expiresIn: '24h'}) 

                res.json({success:true, message:"Authentication 

                    successful", token: token }); 

              } 

            }) 

          } 

         } 

      })(req, res); 

    } 

  } 

}; 

7) Resetting or Changing Passwords:

Resetting or changing passwords requires 2 simple functions in passport-local-mongoose:

setPassword function and changePassword function

When a user forgets the password then the SetPassword is used

For setPassword code is:

user.setPassword(req.body.password, function(err, user){ ..

When the user wants to change the password then the ChangePassword is used.

For change password code is:

user.changePassword(req.body.oldpassword, req.body.newpassword, function(err) ...

Users can directly call them in their router files.

Conclusion:

Well, we’re finally at the end. In the above article, you will learn how to implement local authentication using Passport in a Node.js application along with resetting or changing the passwords. We hope you liked this tutorial and perhaps got some inspiration for your next project. Happy coding!

Leave a Reply

Your email address will not be published.