Authentication in Next.js
Understand the core building blocks of authentication in the App Router — sessions, cookies, and protecting routes.
The Building Blocks
Next.js has no built-in authentication system — instead, it gives you the primitives (cookies, Server Actions, middleware) to build one, or to integrate a dedicated library. Understanding the primitives first makes any library you later choose much easier to reason about.
Cookies
Store a session identifier that persists across requests, read via cookies() on the server.
Server Actions
Verify credentials and set the session cookie after a successful login.
Middleware
Redirect unauthenticated visitors away from protected routes before they render.
A Basic Session Cookie Flow
// app/actions.ts'use server';import { cookies } from 'next/headers';
export async function login(formData) { const email = formData.get('email'); const password = formData.get('password');
const user = await verifyCredentials(email, password); if (!user) return { error: 'Invalid credentials' };
const sessionToken = await createSession(user.id); cookies().set('session', sessionToken, { httpOnly: true, secure: true, sameSite: 'lax', path: '/', });
return { error: null };}Setting httpOnly: true prevents client-side JavaScript from reading the session cookie at all — a key defense against cross-site scripting (XSS) attacks stealing a session.
Reading the Session in a Server Component
// app/dashboard/page.tsximport { cookies } from 'next/headers';import { redirect } from 'next/navigation';
export default async function DashboardPage() { const sessionToken = cookies().get('session')?.value; const user = sessionToken ? await getUserFromSession(sessionToken) : null;
if (!user) { redirect('/login'); }
return <h1>Welcome, {user.name}</h1>;}For protecting many routes at once rather than repeating this check per page, combine this pattern with middleware — checking for the cookie's presence there, and doing the full session verification in the actual route.
Using an Auth Library
For production apps, most teams use a dedicated library — such as Auth.js (formerly NextAuth.js), Clerk, or Lucia — rather than hand-rolling every detail. These handle password hashing, OAuth provider integration (Google, GitHub sign-in), session storage, and CSRF protection correctly out of the box.
Even when using a library, understanding cookies, Server Actions, and middleware means you can read that library's source, debug its behavior, and configure it confidently instead of treating it as a black box.
FAQs
No — store only an opaque session token or ID, and look up the actual user data server-side from your database or session store.
It's a good first gate, but always re-verify the session server-side in the actual page or Route Handler too — never rely on a single check to be the sole line of defense.
Summary
Cookies, Server Actions, and middleware are the building blocks authentication is built from in Next.js, whether hand-rolled or provided by a library. Next, you'll connect a real database to your app.