Open In App
Related Articles

Node.js authentication using Passportjs and passport-local-mongoose

Like Article
Save Article
Report issue
Passport is the authentication middleware for Node. It is designed to serve a singular purpose which is to authenticate requests. It is not practical to store user password as the original string in the database but it is a good practice to hash the password and then store them into the database. But with passport-local-mongoose you don’t have to hash the password using the crypto module, passport-local-mongoose will do everything for you. If you use passport-local-mongoose this module will auto-generate salt and hash fields in the DB. You will not have a field for the password, instead, you will have salt and hash. Why salting of password is needed If the user simply hashes their password and if two users in the database have the same password, then they’ll have the same hash. And if any one of the passwords is hacked then the hacker can access every account using the same password because users with the same password will have the same hash fields. So before we hash it, we prepend a unique string. Not a secret, just something unique. so the hash is completely different for every salt. Steps to perform the operation First let’s generate an express app, then install the needed modules
> npm install passport passport-local mongoose passport-local-mongoose --save
1.First create a directory structure as below :
2.Create model/user.js file which defines user schema
// importing 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
// export userschema
 module.exports = mongoose.model("User", UserSchema);

Note that here in this schema we did not add any field for password unlike we do normally. This is because passport-local-mongoose doesn’t need it. Here we did not add any methods to hash our password or to compare our passwords as we do normally for authentication because passport-local-mongoose will do all that for us. 3.Configure Passport/Passport-Local in app.js : In app.js first, you have to initialize the passport

The passport will maintain persistent login sessions. In order for persistent sessions to work in the passport, the authenticated user must be serialized to the session and deserialized when subsequent requests are made. With passport-local-mongoose it is

The serialize and deserialize code can be slightly different if you are not using passport-local-mongoose with the passport. Now we have to define the strategies for passport. For passport local mongoose the code is
const User = require('./models/user');
const LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(User.authenticate()));

If you are using only passport without passport-local-mongoose the local strategy can be quite different i.e.) you will have to write code to compare passwords and all. Here just this 2 lines are enough 4.Create route/user.js file : First import the user-schema along with other necessary modules
// importing modules 
const express = require('express'); 
const router = express.Router(); 
// importing User Schema 
const User = require('../model/user');

5.For registering : Now for registering the code should be"/register", function (req, res) {
    User.register(new User({ email:, username: req.body.username }), req.body.password, function (err, user) {
        if (err) {
            res.json({ success: false, message: "Your account could not be saved. Error: " + err });
        else {
            req.login(user, (er) =& gt; {
                if (er) {
                    res.json({ success: false, message: er });
                else {
                    res.json({ success: true, message: "Your account has been saved" });

See in the above code we did not define our password in New user. Instead, we use the password with the User.Register() which is a passport-local-mongoose function. Now if you check your database for your saved user, it will be like below
    "_id" : ObjectId("5ca8b66535947f4c1e93c4f1"),
    "username" : "username you gave",
    "email" : "email you gave",
    "salt" : "4c8f6e009c4523b23553d9479e25254b266c3b7dd2dbc6d4aaace01851c9687c",
    "hash" : "337de0df58406b25499b18f54229b9dd595b70e998fd02c7866d06d2a6b25870d23650
    "__v" : 0
You can notice that there is no field for password at all, instead passport-local-mongoose created salt and hash for you, that too you didn’t have to define salt and hash fields in your schema. Passport-local-mongoose will keep your username unique, ie if username already exist it will give “UserExistsError”. 5.For login : Now for login"/login", 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 {
                    const token = jwt.sign({ userId: user._id, username: user.username }, secretkey, { expiresIn: "24h" });
                    res.json({ success: true, message: "Authentication successful", token: token });
        })(req, res);

6.Resetting or changing passwords : You can reset or change passwords using 2 simple functions in passport-local-mongoose. They are setPassword function and changePassword functions. Normally setPassword is used when the user forgot the password and changePassword is used when the user wants to change the password. for setPassword code is
// user is your result from userschema using mongoose id
 user.setPassword(req.body.password, function(err, user){ ..
For changePassword
// user is your result from userschema using mongoose id
  user.changePassword(req.body.oldpassword, req.body.newpassword, function(err) ...
You can directly call them in your router files

Last Updated : 14 Sep, 2022
Like Article
Save Article
Share your thoughts in the comments
Similar Reads