Building an e-Commerce website with Node – Part 21 – Using passport and passport-local libraries for authentication

The passport is an authentication middleware for Node.js. Using passport you can authenticate using a username and a password, Facebook, Twitter etc. You can learn more about passport at the following link: http://passportjs.org/.

First of all we need to require the passport library. In the server.js file just below the var MongoStore go ahead and type the following code:


var passport = require(‘passport’);

Next, we want to install the passport library. We do that using the terminal. In your terminal go ahead and install passport using the following command:


npm install passport --save

Now, we need to create a passport.js file. In the config folder create a file and name it passport.js.

In order to use passport.js in one of our routes (specifically in the log in) we need to configure it first. It is just a new rule in the config file so the login can use it. It is actually a middleware. We also need to require a new library called passport-local which is a username and password authentication strategy for Passport and Node.js.


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

Now we need to install the passport-local library. The passport-local library is used to handle user authentication with username and password. You can learn more about passport-local at the following link: https://www.npmjs.com/package/passport-local. Go to your terminal and type in the following comand:


npm install passport-local --save

Now, in the passport.js we need to create three sections, so our code will stay organized.

Section 1 – Serialize and deserialize user objects.
Section 2 – Write the middleware that will process the login mechanism.
Section 3 – A custom function for validation.

Section 1


// Section 1 - Serialize and Desirialize user objects
passport.serializeUser(function(user, done) {
  done(null, user._id);
});

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

Serialization means that data structures are translated into a format that can be stored. Our data structure is the user object. This data will be stored in connect-mongo.
The key of user object provided in the second argument of the callback function (which is user._id), in serialized functions it is saved in session and it is used to retrieve the whole object via the deserialize function.

Note:
The _id is automatically given by the mongoDB.

So, later on if you want to access a user that is logged in you just type req.user.
In the deseriaze part, findById is one of mongoose methods. So, the key here is the id.

That is all about the first section.

Section 2


// Middleware
passport.use('local-login', new LocalStrategy({
  usernameField: 'email',
  passwordField: 'password',
  passReqToCallback: true
}, function(req, email, password, done) {
  User.findOne({ email: email}, function(err, user) {
    if (err) return done(err);

    if (!user) {
      return done(null, false, req.flash('loginMessage', 'No user has been found'));
    }

    if (!user.comparePassword(password)) {
      return done(null, false, req.flash('loginMessage', 'Wrong Password'));
    }
    return done(null, user);
  });
}));

First you need to name the middleware. I named it “local-login”.
Next we created a new instance of LocalStrategy object and pass it the required fields. By default, LocalStrategy uses two fields, username and password.
Next, there is a function to validate everything and give the appropriate messages. I think it is self explanatory.

Section 3


// Custom function to validate
exports.isAuthenticated = function(req, res, next) {
  if (req.isAuthenticated()) {
    return next();
  }
  res.redirect('/login');
}

isAuthenticated is the name I have given to the function.
This function checks if the user is logged in or not.
If the user is authenticated then just go ahead.
If the user is not authenticated then redirect the user to the login page (which is not yet created).

Leave a Reply