CodePark/ questions / Auth & security
START PRACTICINGPRACTICE
Frontend question · Next.js › Auth & security

How do you implement authentication and protect routes in the App Router?

// lib/dal.ts
import "server-only";
import { cache } from "react";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";

export const verifySession = cache(async () => {
  const token = (await cookies()).get("session")?.value;
  const session = await decrypt(token);
  if (!session?.userId) redirect("/login");
  return { userId: session.userId };
});

Store the session in a secure cookie, and check it in layers. The real check sits next to the data.

Authentication. Usually you store the session in an encrypted httpOnly cookie, which JavaScript in the page cannot read. The cookie holds either:

  • a stateless signed token, or
  • an ID that points to a session in a database.

Libraries such as Auth.js, or a hosted provider, handle much of this.

Protection in layers:

  • Middleware does fast, optimistic checks. For example, it redirects to /login when there is no session cookie.
  • A data access layer does the real check. Write a verifySession() function wrapped in React cache(). Every data read, Server Action and Route Handler calls it before touching data.

Don't rely on layouts for auth checks either. Layouts don't re-render on every navigation.

Checking close to the data is safer. If middleware is bypassed, or a page forgets its check, nothing leaks.

  • Store the session in an encrypted, httpOnly cookie.
  • Use middleware only for optimistic redirects.
  • A data access layer does the real session check.
  • Every Server Action and Route Handler must check the session.
  • Layouts are not a reliable place for auth checks.