TM#005 — How to implement Passport Local Strategy with PostgreSQL
Passport is authentication middleware for Node.js. It is being used by NodeJs, Laravel, and many other technologies for user authentication. If you go to passportjs website, you will see a plethora of strategies, which include the authentication from Google, Facebook, GitHub, etc. The one we will be discussing is the LocalStrategy, It allows the user to log in by inputting the credentials stored in a database like MongoDB or PostgreSQL.
There are a lot of tutorials available which will show how to implement passport Local Strategy using MongoDB. Mongoose is a npm package that provides some very easy functionality for the mongoDB and passport authentication is implemented very easily, the procedure is a bit convoluted for Postgres.
We will need the following packages for the application:
const express = require('express');
const app = express();
const bcrypt = require('bcrypt');
const passport = require('passport');
const flash = require('express-flash');
const session = require('express-session');
const pgSession = require('connect-pg-simple')(session);
const knex = require('knex');
After setting up the basic login and register routes and their templates, we will configure the passport middleware:
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcrypt');
function initialize(passport, getUserByEmail, getUserById) {
const authenticateUser = async (email, password, done) => {
const user = await getUserByEmail(email);
if (user.length == 0) {
return done(null, false, { message: 'No user with that email' });
}
try {
if (await bcrypt.compare(password, user[0].user_password)) {
return done(null, user[0]);
} else {
return done(null, false, { message: 'Password incorrect' });
}
} catch (e) {
return done(e);
}
};
passport.use(new LocalStrategy({ usernameField: 'email' }, authenticateUser));
passport.serializeUser((user, done) => done(null, user.user_id));
passport.deserializeUser(async (id, done) => {
const user = await getUserById(id);
return done(null, user[0]);
});
}
module.exports = initialize;
The above code is available in passport documentation, getUserByEmail
and getUserById
are functions that get the users from the database. Serialize
and Deserialize
are also passport functions that store the user data in sessions. In order for our data to persist, we need to set up a sessions table in our database and this is where connect-pg-simple
is used
app.use(
session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
store: new pgSession({
conString: 'postgres://<user>:<password>@localhost:5432/<dbname>',
}),
);
})
If your PostgreSQL database has some default user settings, you can use this conString
to mention those settings and after that, you can use passport authentication with the Passport Local Strategy
by using PostgreSQL database.
And this is how you can implement authentication in your node js app with passport.
This article is written by Asfand Yar Aftab, a full-stack engineer (contractor) at Antematter.io