How to Add Authentication to an Express.js App (2026 Guide)
Complete guide to Express.js auth. Covers Passport.js, JWT, express-session, and managed providers for Node.js APIs.
Express.js is the most widely used Node.js web framework, with over 35 million weekly npm downloads. It powers the backend for countless React, Vue, and mobile applications. But Express is intentionally minimal — it provides routing, middleware, and not much else. Authentication is entirely your responsibility.
This guide covers every practical approach to express auth in 2026, from the venerable Passport.js to modern JWT patterns and managed providers.
How Express Auth Architecture Works
Express uses middleware functions that run in sequence on each request. Authentication in Express means inserting a middleware that validates credentials (on login) or verifies tokens/sessions (on subsequent requests) before your route handlers execute.
The standard Express auth flow has three parts:
- Authentication middleware validates credentials or tokens. For sessions, this means checking a cookie against a session store. For JWTs, this means verifying the token signature and expiry.
- Session or token management persists the auth state. express-session stores sessions in Redis or MongoDB. JWT solutions send signed tokens to the client.
- Route protection applies auth checks to specific routes. You create middleware functions that check
req.userand return 401 if missing.
Express gives you complete freedom in how you implement each part. That freedom is both its strength and the source of most security mistakes.
Common Express Auth Approaches Compared
Passport.js
Passport.js has been the standard Express auth middleware for over a decade. It provides 500+ authentication strategies covering OAuth, SAML, local username/password, JWT, and more. It receives over 4 million weekly npm downloads.
What works well:
- 500+ strategies for virtually every auth provider
- Modular — install only the strategies you need
- Massive community with solutions for most edge cases
- Works with both sessions and tokens
- passport-local for username/password, passport-google-oauth20 for Google, etc.
Where it falls apart:
- Intentionally low-level — you build significant infrastructure around it
- Strategy configuration is verbose and repetitive
- Serialization/deserialization boilerplate for session management
- Many strategies are community-maintained with varying quality
- Debugging auth failures through the strategy chain is difficult
JWT with express-jwt
For stateless API authentication, express-jwt validates JWT tokens and attaches the decoded payload to req.user. No sessions, no database lookups on each request.
What works well:
- Stateless — no session store needed
- Works with any client (web, mobile, third-party)
- Simple middleware: one function validates all tokens
- Scales horizontally without session synchronization
Where it falls apart:
- Tokens cannot be revoked until they expire (without a blacklist)
- Token refresh rotation adds complexity
- Storing tokens client-side creates XSS risk
- No built-in social login or OAuth flow
For modern projects, the jose library provides JWT signing and verification with updated algorithms (Ed25519, ES256) and is actively maintained.
express-session with Database Store
Session-based auth stores a session ID in a signed cookie and keeps session data in a database (Redis, MongoDB, PostgreSQL). The session ID is validated on each request.
What works well:
- Sessions can be revoked instantly by deleting from the store
- No sensitive data stored client-side
- Simple to implement with connect-redis or connect-mongo
- Works well for traditional server-rendered apps
Where it falls apart:
- Requires a session store (Redis or database)
- Does not work for third-party API consumers
- Horizontal scaling requires shared session storage
- CSRF protection needed for cookie-based auth
Auth0 Express SDK
Auth0’s Express OpenID Connect library (express-openid-connect) provides managed auth without Passport.js. It handles the entire OAuth/OIDC flow with a few lines of configuration.
What works well:
- Complete auth in 5 lines of middleware configuration
- Universal Login handles the entire OAuth flow
- Free up to 25,000 monthly active users
- Enterprise SSO with SAML and OIDC
Where it falls apart:
- Redirect to Auth0’s hosted login page adds latency
- Pricing grows with MAU count
- Less control over the auth flow
- Vendor lock-in for identity data
The Real Problem: Auth Is Only Half the Battle
Express handles HTTP requests. Auth middleware protects routes. But authentication does not make money. If you are building a SaaS with an Express backend, you need Stripe for payments, subscription management, and webhooks.
Building Stripe integration after auth means webhook handlers, customer-to-user mapping, subscription state management, and a billing portal. That is another 1-2 weeks of work on top of auth.
How Beag Simplifies Express Auth and Payments
Beag combines auth and payments into a single integration. Instead of configuring Passport.js for auth and then building Stripe webhooks separately, you add the Beag script tag to your frontend and get:
- Authentication with email, social login, and magic links
- Stripe payments with checkout, subscriptions, and customer portal
- User-to-customer mapping handled automatically
- Session data accessible via API from your Express routes
For indie hackers and small teams, this eliminates the two most time-consuming infrastructure pieces. See how it fits into the indie hacker tech stack.
Choosing the Right Approach
| Solution | Cost | Setup Time | Auth + Payments |
|---|---|---|---|
| Passport.js + sessions | Free | 2-4 hours | Auth only |
| express-jwt | Free | 1-3 hours | Auth only |
| express-session + Redis | Free | 2-4 hours | Auth only |
| Auth0 Express SDK | Free up to 25K MAU | 1-2 hours | Auth only |
| Beag | $19/month | 15 minutes | Both included |
If your Express backend serves a React frontend, see our React auth guide for client-side patterns. For the complete list of framework guides, browse the guide hub.
What to Do Next
- Pick your auth pattern. Sessions for web apps, JWTs for APIs.
- Decide your scope. Auth only, or auth plus payments?
- Factor in total cost. Open source middleware still costs engineering hours.
- Start building. Try Beag free for 7 days or explore the docs.
Frequently Asked Questions
Is Passport.js still worth using in 2026?
Passport.js remains the most popular auth middleware for Express with over 4 million weekly npm downloads and 500+ authentication strategies. It is worth using when you need social login with multiple providers or enterprise SSO. For simple JWT auth, many developers now skip Passport and use express-jwt or jose directly.
Should I use sessions or JWTs with Express?
Use sessions (express-session + connect-mongo/connect-redis) for traditional web apps where you control the frontend. Sessions can be revoked instantly by deleting them from the store. Use JWTs for stateless APIs consumed by mobile apps or third-party clients where you cannot share cookies.
How do I secure Express API routes with authentication?
Create an auth middleware that validates the session cookie or JWT on each request. Attach the decoded user data to req.user. Apply the middleware to protected routes or route groups using router.use(). Always validate tokens server-side -- never trust client-side checks alone.
What is express-jwt and when should I use it?
express-jwt is middleware that validates JWT tokens and attaches the decoded payload to req.user. It is lighter than Passport when you only need JWT validation without social login or multiple strategies. For new projects in 2026, the jose library is an alternative that handles JWT signing and verification with modern algorithms.
How long does it take to add auth to an Express app?
Basic session-based auth with Passport local strategy takes 2-4 hours. JWT auth with express-jwt takes 1-3 hours. Adding social login with Passport OAuth strategies takes an additional 1-2 hours per provider. If you need auth and payments together, Beag handles both in about 15 minutes.
Skip the Auth and Payments Headaches
Beag handles authentication and Stripe payments with a single script tag. Ship your SaaS faster.
Start 7-day free trial