Back to resources
// guide · auth

Authentication in a Next.js app

Auth is where people mess up most, and where it costs the most. Sessions or JWT, where to store the token, where to put the checks: here's the authentication foundation I build, simple and solid.

GuideJul 28, 2026~8 min · intermediate
Next.jssessionsJWTcookiesOAuthmiddleware
01

Sessions vs JWT

Two ways to remember a user is logged in. The debate is eternal; in practice the choice is simple for a typical SaaS.

session (server)

revocable.

state lives in DB / Redis
instant logout possible
ideal for a SaaS
JWT (stateless)

scalable.

no server-side storage
hard to revoke before expiry
good for service-to-service
i

By default, for a SaaS, I go with sessions: being able to log a user out immediately beats the stateless elegance of JWT.

03

Where to check

Middleware protects groups of routes at once (redirect if no session). But it doesn’t replace the check in each API route: middleware guards the door, the route guards the safe.

middleware.tscopy
// middleware.ts — protege un groupe de routes d'un coup
import { NextResponse } from "next/server";
export function middleware(req) {
const session = req.cookies.get("session");
if (!session) return NextResponse.redirect(new URL("/login", req.url));
return NextResponse.next();
}
export const config = { matcher: ["/dashboard/:path*", "/settings/:path*"] };
!

Never rely on middleware alone for data security: every route must re-check session AND resource ownership. That’s the IDOR flaw from the basic security holes.

04

OAuth & the rest

for “sign in with Google/GitHub,” a proven lib (Auth.js) rather than rolling your own;
hash passwords with bcrypt/argon2 — never plaintext, never a fast hash;
rate limiting on login to block brute-force;
session expiry + rotation, and logout that truly invalidates server-side.
i

Login rate limiting has its own article: rate limiting and API protection.

05

Sources & further reading

01Next.js — How to implement authentication in Next.jsThe official docs: stateless vs database sessions, recommended cookie options, and why checks belong in a Data Access Layer rather than middleware alone.02Auth.js — Session strategiesThe JWT vs database session trade-off as Auth.js frames it: revocation, “sign out everywhere,” and the ~4096-byte cookie limit.03OWASP — Session Management Cheat SheetThe reference on cookie attributes (HttpOnly, Secure, SameSite) and on regenerating the session ID on every privilege change.04OWASP — Cross-Site Request Forgery Prevention Cheat SheetWhy SameSite=Lax isn't enough on its own, and when to add a synchronizer token or a signed double-submit cookie.05MDN — Using HTTP cookiesThe exact definition of every attribute set in the code above: HttpOnly, Secure, SameSite, Max-Age, Path.06OWASP — Password Storage Cheat SheetArgon2id as first choice, bcrypt (work factor ≥ 10) for legacy systems — how to calibrate password hashing.07RFC 9700 — Best Current Practice for OAuth 2.0 SecurityThe modern OAuth baseline: PKCE required for public clients, exact redirect URIs — what good libraries already do for you.

Solid auth isn't complicated, it's rigorous: revocable sessions for a SaaS, token in an httpOnly cookie, checks in every route and not just middleware, hashed passwords. Don't reinvent the wheel on OAuth — but understand every piece.