User authentication with Passport.js

Aishwarya Babu
3 min readAug 15, 2020

--

Passport.js

Introducing Passport.js

Passport.js is an authentication middleware. It attempts to implement local authentication of users and make logging in/logging out simpler.
It is flexible in the sense that it allows for different authentication strategies (think via Twitter, via our own user database — installed via separate modules that can be combined) and it allows us to specify any route or output during authentication.

The Local Strategy allows us to authenticate users by looking up their data in the app’s database.

Let’s see how can we integrate it.

To get started, let us first create a basic express app using the following command.

npx express-generator

Next, we will install a few modules that we will need.

npm install body-parser express-session passport passport-local bcryptjs mongoose

Now, you might be familiar with body-parser,express-session and mongoose.
passport is the npm module that helps us use Passport.js, passport-local will help us define a ‘local strategy’ (more on that later) and bcryptjs is used to safely hash and store our user’s passwords.

Let’s add these modules to our app.js file.

var bodyParser = require('body-parser');
var session = require('express-session');
var passport = require('passport');
var mongoose = require('mongoose');
var LocalStrategy = require('passport-local');
var mongoose = require('mongoose');
app.use(session({
secret: 'secret',
saveUninitialized: true,
resave: true
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyParsor.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(cookieParser());
passport.serializeUser(function(user,done){
done(null,user.id);
});
passport.deserializeUser(function(id,done){
User.findById(id, function(err,user){
done(err,user);
})
})
var mongoURI = YOUR_MONGO_URI;
mongoose.connect(mongoURI, {
useUnifiedTopology: true,
useNewUrlParser: true,
})
.then(() => console.log('DB Connected!'))
.catch(err => {
console.log(err);
});
var conn = mongoose.connection;

Make sure you do not mess up the order of the variables. It is really important you follow the order.

Now the fun part!
Before we go ahead and setup passport, let’s take a look at the user model.

var mongoose = require("mongoose");var bcrypt = require("bcryptjs");var userSchema = mongoose.Schema({
name: String,
email: String,
username: String,
password: String
});
var User = module.exports = mongoose.model("User", userSchema);

So as you can see, we have setup a basic user model. Now we need to hash our password values. To do this, we take the help of bcrypt.
As you can guess by the name, bcrypt is a library that hashes the password and stores it. We can implement this in our user model now.

module.exports.createUser = function(newUser, callback) {
bcrypt.genSalt(5,function(err,salt){
bcrypt.hash(newUser.password,salt,function(err,hash){
newUser.password = hash;
newUser.save(callback);
});
});
}

Now, we need to add a few more methods in the users model.
comparePassword
compares two passwords, one that is a hashed value, and determines if it is the same.
getUserByUsername returns a user with the specified username.

module.exports.comparePassword = function(candidatePassword, hash, callback){
bcrypt.compare(candidatePassword, hash, function(err, isMatch) {
callback(err, isMatch);
});
}
module.exports.getUserByUsername = function(username, callback){
var query = {username: username};
User.findOne(query, callback);
}

So now we define the Local Strategy. What a local strategy is, is basically a way to specify how to authenticate users.

You have a user trying to login. What do you do?
You first check if the user is already registered in your database. If they haven’t registered yet, then you throw an error. If they are, they you check if the password specified by the user is the same as the password registered in the database. This is exactly what we wish to accomplish in the following lines of code.
Now, let’s define the local strategy in the app.js file.

passport.use(new LocalStrategy(
function(username, password, done) {
User.findOne({username:username}, function(err, user){
if(err) throw err;
if(!user)
done(null,false, {message: 'Unknown user'});
User.comparePassword(password,user.password,function(err, isMatch){
if(err)
done(err);
if(isMatch)
done(null,user);
else
done(null, false, {message: 'Invalid password'});
});
});
}
));

All that’s left to do now is add the routes and a simple view page to test out our app.

login.ejs

signup.ejs

Now, run the app and try to sign up and sign in!

Here’s the Github repository for the code : https://github.com/aishwarya-29/development/tree/master/User%20authentication%20using%20Passport

Happy Coding :)

--

--

Aishwarya Babu
0 Followers

Web & Android Developer. ML Enthusiast. Competitive Coder. And much much more :)