Passport JS
Written By: Avinash Malhotra
Updated on
Authentication using Passport JS
Passport or PassportJS is NodeJS and ExpressJS Compatible middleware for authentication. Passport JS uses different different strategies to authenticate requests. This includes username and password authentication or LocalStrategy, Facebook, Twitter, Apple, github etc authentication and 500+ total strategies.
The purpose to use passport in NodeJS or Express is to authenticate requests by using strategies. Like admin can access all pages, but users are not allowed for certain requests.
Modules required for passport
- expressjs
- express-session
- body-parser
- mongoose
Install Passport JS
passport is available on npm as passport. Install passport and include passport in main app through module.
Passport JS is installed in NodeJS Application.
Install Passport Local
Now install passport-local strategy to authenticate username and password.
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
Configure Passport
const express=require('express');
let app=express();
const User=require('./models/user');
const db=require('./mdb');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(function (user, done) {
done(null, user.id);
});
passport.deserializeUser(function (user, next) {
next(null, user);
});
passport.use('local', new LocalStrategy((username, password, done) => {
user.find({ username: username }).then(user=>{
if( user.length==0 ){
return done(null, null, { message: 'No user found!' });
}
else if (user[0].password !== password) {
return done(null, null, { message: 'Password is incorrect!' });
}
else{
return done(null, user, null);
}
})
}
));
function isAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
next();
} else {
res.status(403).send('Forbidden');
}
}
Passport Local Authentication Example
Here is a complete example of how to authenticate local in passport. We are using Mongoose for MongoDB Connections in example.
Modules used in local authentication
- dotenv
- expressjs
- express-session
- body-parser
- nunjucks
- mongoose
require('dotenv').config();
const express=require("express");
const path=require("path");
const nunjucks=require("nunjucks");
const app=express();
const session=require('express-session');
app.set('trust proxy', 1);
app.use(session({
secret:"session",
resave:false,
saveUninitialized:true,
cookie:{secure:false}
}))
const mongoose=require('mongoose');
const dao=require('./dao');
const Car=require("./models/car");
const Admin=require("./models/admin");
const bodyParser=require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser( (user, done)=> {
done(null, user.id);
});
passport.deserializeUser( (user, next)=> {
next(null, user);
});
passport.use( new LocalStrategy({ usernameField: 'name',passwordField:'pass' },(username, password, done) => {
Admin.find({ name: username }).then((err, user) => {
if (err) { return done(err); }
if (!user) { return done(null, null, { message: 'No user found!' }); }
if (user.pass !== password) {return done(null, null, { message: 'Username or password is incorrect!' }) }
return done(null, user, null);
});
}
));
function isAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
next();
} else {
res.status(403).render('login.html',{msg:"Forbidden"});
}
}
app.use(express.static(path.resolve(__dirname,'public')));
nunjucks.configure(path.resolve(__dirname,'public'),{
express:app,
autoscape:true,
noCache:false,
watch:true
});
app.get("/",(req,res)=>{
res.status(200).render("home.html",{name:"Home Page"})
});
app.get("/addcar",(req,res)=>{
let carname=new Car({
_id:mongoose.Types.ObjectId(),
name:req.query.name,
brand:req.query.brand,
type:req.query.type,
price:req.query.price,
fuel:req.query.fuel
});
carname.save()
.then(data=>console.log(data))
.catch(err=>console.warn()err);
});
app.get("/login",(req,res)=>{
res.status(200).render('login.html',{name:"Login"});
});
app.get('/adminlogin', isAuthenticated, (req, res) => { res.render('admin-login.html',{name:"admin"}) });
app.get('/logout', (req, res) => {
if (req.session) {
req.session.destroy((err)=> {
if(err) {
return next(err);
} else {
res.clearCookie('connect.sid');
req.logout();
if (!req.user) {
res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate');
}
res.render('login.html',{ msg:"Logout Successfully"});
}
});
}
});
app.post("/login",(req,res)=>{
passport.authenticate('local', (err, user, info) =>{
if (err) {
res.render('login.html', { error: err });
}
else if (!user) {
res.render('login.html', { errorMessage: info.message });
}
else {
//setting users in session
req.logIn(user, function (err) {
if (err) {
res.render('login.html', { error: err });
} else {
res.render('admin-login.html',{ name:user.name});
}
})
}
})(req, res);
});
app.get("/**",(req,res)=>{
res.status(404).render('error.html',{name:"404 - Page not found"})
})
app.listen(process.env.PORT,()=>{
console.log(`App running at http://127.0.0.1:${process.env.PORT}`);
});