Authentication confirms who a user is; Express doesn't ship with an opinionated way to do it, giving you a choice between several well-established strategies. This lesson maps out the landscape before diving into each in detail.
The Main Authentication Approaches
Session-based authentication stores a session identifier in a cookie, with the actual user data kept server-side (in memory, Redis, or a database). Token-based authentication (typically JWT) issues a signed token to the client, which sends it back on every request, no server-side session storage needed.
Passport.js is a middleware framework that standardizes many authentication strategies (local username/password, Google, GitHub, and more) behind one consistent API, rather than being a strategy itself.
Sessions rely on server-side storage keyed by a cookie; JWTs are self-contained and verified without any server-side lookup.
Choosing an Approach
Traditional server-rendered site -> sessions (express-session)
Stateless REST/mobile API -> JWT
Multiple auth providers (Google, GitHub) -> Passport.js strategies
Third-party login without password -> OAuth 2.0
Sessions fit naturally with server-rendered apps that already use cookies for everything else.
JWTs fit stateless REST APIs, especially ones consumed by mobile apps or SPAs across different domains.
Passport.js is a strategy-agnostic toolkit, it can implement either sessions or tokens under the hood.
OAuth is specifically for delegating authentication to a third party (Google, GitHub, etc.), not a general auth mechanism on its own.
Authentication Strategy Cheatsheet
A quick comparison of the main approaches covered in this section.
Strategy
State
Best Fit
Sessions
Server-side (memory/Redis/DB)
Server-rendered apps, traditional websites
JWT
Stateless (self-contained token)
REST APIs, mobile apps, SPAs
Passport.js
Depends on strategy used
Apps needing multiple login providers
OAuth 2.0
Delegated to a third party
"Sign in with Google/GitHub" flows
Authentication vs Authorization
Authentication answers "who are you?", verifying identity, typically via credentials, a token, or a session. Authorization answers "what are you allowed to do?", checking permissions or roles after identity is already established. Middleware for each is usually separate: an authenticate middleware first, then an authorize(role) middleware after.
Regardless of which session/token strategy you choose, passwords must never be stored in plain text. Use a slow, purpose-built hashing algorithm like bcrypt, never a fast general-purpose hash like MD5 or SHA-256 alone.
Storing passwords in plain text or with a fast, non-purpose-built hash.
Confusing authentication (identity) with authorization (permissions).
Choosing JWTs for a traditional server-rendered site just because they're popular, when sessions fit more naturally.
Implementing OAuth manually instead of using a mature library like Passport.js.
Key Takeaways
Sessions and JWTs are the two dominant authentication state strategies in Express apps.
Passport.js standardizes many strategies behind one consistent middleware API.
OAuth delegates identity verification to a third-party provider like Google or GitHub.
Authentication (who you are) and authorization (what you can do) are separate concerns with separate middleware.
Pro Tip
Pick session-based auth by default for classic server-rendered apps and JWTs by default for pure APIs, switching strategies mid-project is far more work than choosing the right one up front based on how the client actually consumes your API.
You now understand the authentication landscape. Next, implement stateless authentication in the JWT Authentication lesson.