Passport.js
Part of the Backend Developer Roadmap
In short
Email login today, Google tomorrow, GitHub next week. Passport.js gives each login method its own plug-in 'strategy', so your routes don't turn into a jungle of if-else.
A widely used Node.js authentication middleware supporting dozens of 'strategies' (local, JWT, Google, GitHub, etc.) behind one consistent API.

Think of it like this
One checkpoint, many stamps
At a busy checkpoint, one officer handles every visitor. Show a college ID and he uses one stamp; show a visitor pass and he picks another. The desk stays the same; only the check changes. Passport is that desk, and each strategy is a stamp.
Watch it happen
A local login through Passport
1/5POST /login arrives with an email and password in the body.
The big ideas
What you need to know
Strategies are plug-ins
passport-local, passport-jwt, passport-google-oauth20 and many more. Install only the ones you need.
You write verify()
Passport never touches your database. Your verify function decides whether the credentials are good.
Sessions are optional
Use serializeUser with sessions, or pass session: false for token-based APIs like JWT.
Same middleware everywhere
Routes just call passport.authenticate(name), so adding a login method barely touches them.
See it in code
Walk through the code
1import passport from "passport";2import { Strategy as LocalStrategy } from "passport-local";3import bcrypt from "bcrypt";4 5passport.use(new LocalStrategy({ usernameField: "email" }, async (email, password, done) => {6 const user = await db.users.findByEmail(email);7 if (!user || !(await bcrypt.compare(password, user.passwordHash))) {8 return done(null, false, { message: "Wrong email or password" });9 }10 return done(null, user);11}));12 13passport.serializeUser((user: any, done) => done(null, user.id));14passport.deserializeUser(async (id: string, done) => done(null, await db.users.find(id)));15 16app.post("/login", passport.authenticate("local"), (req, res) => res.json({ id: req.user!.id }));1/4Register the local strategy. It reads email and password from the body and hands them to you.
This assumes express-session is set up and app.use(passport.session()) runs before your routes.
Save yourself the pain
Common mistakes
Oops
Telling users 'email not found' in one case and 'wrong password' in the other.
Do this instead
That lets attackers check which emails are registered. Use one message for both.
Oops
Forgetting app.use(passport.session()) and wondering why req.user is empty.
Do this instead
With sessions, add express-session and then passport.session() before your routes, in that order.
Your mission
Plug in a second strategy
Quick check
With Passport's local strategy, who checks whether the password is correct?
Go deeper
- 1Set up Passport's local strategy for email/password login.
- 2Add a second strategy, e.g. Google OAuth, alongside your local one.
- 3Learn how Passport serializes/deserializes a user into the session.
More topics at this stop
Stuck on this topic? Ask an Insider
Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.