Skip to content

2. PassportJS

Passport.js is a flexible authentication middleware for Node.js that supports many strategies like local username/password, Google, Facebook, JWT, etc. Here’s a basic setup using the local strategy for both authentication and authorization.

βœ… 1. Passport (Local Strategy)

1.1 Example 01

Absolutely! Here’s a simple and complete example of using passport.js for local authentication (username & password login) with Express.js.

πŸ”§ Tech Stack

  • express
  • passport
  • passport-local
  • express-session
  • bcrypt (for password hashing)

πŸ“ File Structure

.
β”œβ”€β”€ app.js
└── users.js (in-memory fake DB)

1. πŸ“¦ Install Dependencies

Terminal window
npm install express passport passport-local express-session bcrypt

2. πŸ“„ Simple in-memory user β€œdatabase”

users.js
const bcrypt = require('bcrypt');
const users = [];
async function addUser(username, password) {
const hashed = await bcrypt.hash(password, 10);
users.push({ id: Date.now().toString(), username, password: hashed });
}
function findUser(username) {
return users.find(user => user.username === username);
}
module.exports = { users, addUser, findUser };

3. πŸ“„ Main Express App with Passport Setup

app.js
const express = require('express');
const session = require('express-session');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcrypt');
const { users, addUser, findUser } = require('./users');
const app = express();
app.use(express.urlencoded({ extended: false }));
// Session middleware
app.use(session({
secret: 'secret-key',
resave: false,
saveUninitialized: false
}));
// Passport initialization
app.use(passport.initialize());
app.use(passport.session());
// Configure Passport strategy
passport.use(new LocalStrategy(async (username, password, done) => {
const user = findUser(username);
if (!user) return done(null, false, { message: 'User not found' });
const match = await bcrypt.compare(password, user.password);
if (!match) return done(null, false, { message: 'Wrong password' });
return done(null, user);
}));
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
const user = users.find(u => u.id === id);
done(null, user);
});
// Routes
app.get('/', (req, res) => {
res.send(`<h1>Home</h1>
${req.isAuthenticated() ? `<p>Welcome ${req.user.username}</p><a href="/logout">Logout</a>` : '<a href="/login">Login</a>'}
`);
});
app.get('/login', (req, res) => {
res.send(`
<h2>Login</h2>
<form method="POST" action="/login">
<input name="username" placeholder="Username" required>
<input name="password" placeholder="Password" type="password" required>
<button type="submit">Login</button>
</form>
`);
});
app.post('/login', passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/login'
}));
app.get('/logout', (req, res) => {
req.logout(() => {
res.redirect('/');
});
});
// Create a sample user
addUser('admin', 'password123').then(() => {
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
});

βœ… How it Works

  1. passport-local checks the username and password.
  2. If valid, Passport serializes the user to the session.
  3. Authenticated users can now be recognized via req.isAuthenticated() and req.user.

πŸš€ Try It Out

  • Go to http://localhost:3000
  • Login with:
    Username: admin
    Password: password123
  • You’ll see a welcome message after logging in!

1.2 Example 02

1. Install dependencies

Terminal window
npm install passport passport-local express-session bcrypt

2. Set up your user model

Assume you’re using something like this (in-memory user example for simplicity):

const users = [
{ id: 1, username: 'admin', passwordHash: '$2b$10$....', role: 'admin' }
];

Use bcrypt to hash passwords.

3. Configure Passport

passport-config.js
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcrypt');
function initialize(passport, getUserByUsername, getUserById) {
passport.use(new LocalStrategy(async (username, password, done) => {
const user = getUserByUsername(username);
if (!user) return done(null, false, { message: 'No user found' });
try {
if (await bcrypt.compare(password, user.passwordHash)) {
return done(null, user);
} else {
return done(null, false, { message: 'Incorrect password' });
}
} catch (e) {
return done(e);
}
}));
passport.serializeUser((user, done) => done(null, user.id));
passport.deserializeUser((id, done) => {
const user = getUserById(id);
done(null, user);
});
}
module.exports = initialize;

4. Set up Express App

app.js
const express = require('express');
const session = require('express-session');
const passport = require('passport');
const initializePassport = require('./passport-config');
const app = express();
// Dummy user methods
const users = [...];
const getUserByUsername = username => users.find(u => u.username === username);
const getUserById = id => users.find(u => u.id === id);
initializePassport(passport, getUserByUsername, getUserById);
app.use(express.urlencoded({ extended: false }));
app.use(session({ secret: 'secret', resave: false, saveUninitialized: false }));
app.use(passport.initialize());
app.use(passport.session());

5. Authentication Route

app.js
app.post('/login', passport.authenticate('local', {
successRedirect: '/dashboard',
failureRedirect: '/login'
}));

6. Authorization Middleware

function checkAuthenticated(req, res, next) {
if (req.isAuthenticated()) return next();
res.redirect('/login');
}
function checkRole(role) {
return function (req, res, next) {
if (req.user && req.user.role === role) return next();
res.status(403).send('Forbidden');
};
}

7. Protected Route

app.get('/dashboard', checkAuthenticated, (req, res) => {
res.send(`Hello ${req.user.username}`);
});
app.get('/admin', checkAuthenticated, checkRole('admin'), (req, res) => {
res.send('Welcome Admin');
});

8. Logout

app.post('/logout', (req, res) => {
req.logout(err => {
if (err) return next(err);
res.redirect('/login');
});
});

βœ… Summary

FeatureHow It’s Handled
Authenticationpassport.authenticate()
AuthorizationMiddleware based on req.user
Sessionsexpress-session + serialize/deserialize

1.3 Passport & Session Handling

These three middlewares in Express + Passport are essential for user authentication using sessions.

1. πŸ” app.use(session({ ... }))

πŸ“Œ What it does:

Sets up session support in Express. This allows your server to store data for a user across multiple HTTP requests (like login state).

🧠 Why it’s needed:

  • Passport uses sessions to remember whether a user is logged in.
  • Without this, every request would be stateless, and you’d have to re-login on every request.

βš™οΈ Config options:

  • secret: used to sign the session ID cookie.
  • resave: false: don’t save session if nothing changed.
  • saveUninitialized: false: don’t save empty sessions.

2. πŸš€ app.use(passport.initialize())

πŸ“Œ What it does:

Initializes Passport. It sets up middleware to handle authentication requests (e.g., login via strategy like local, Google, etc).

🧠 Why it’s needed:

  • Passport needs to hook into Express to handle things like req.login(), passport.authenticate(), etc.
  • Without this, Passport won’t function at all.

3. 🧳 app.use(passport.session())

πŸ“Œ What it does:

Enables Passport session support – it integrates with express-session to persist login state across requests.

🧠 Why it’s needed:

  • After login, Passport serializes the user into the session (using serializeUser()).
  • On every request, Passport automatically restores the user from the session (using deserializeUser()).
  • This enables req.isAuthenticated() and req.user to work.

4. 🧩 How they work together

  1. Login β†’ passport.authenticate() calls req.login(user)
    β†’ stores user.id in the session.

  2. On future requests

    • express-session loads the session from the cookie.
    • passport.session() deserializes the user into req.user.

5. βœ… Summary Table

MiddlewarePurpose
express-sessionStores session cookie + session data
passport.initialize()Sets up Passport functionality
passport.session()Enables persistent login sessions