LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 4219 min read

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 };
}
httpOnly Matters

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.tsx
import { 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.

Why Learn the Primitives First

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.

Next Lesson →

Database Integration