C.W.K.
Stream
Lesson 06 of 09 · published

Protected Routes

~20 min · defense in depth, auth

Level 0Curious
0 XP0/68 lessons0/11 achievements
0/120 XP to next level120 XP to go0% complete

Defense in depth

Don't rely on one auth check. Layer them — each catches what the others miss.

LayerCatches
ProxyBots and casual users hitting protected URLs unauthenticated
LayoutServer-rendered pages that someone reaches without going through the proxy (e.g. preview deployments)
Server Action / Route HandlerProgrammatic POSTs from anywhere on the internet

What each layer is for

Proxy is the redirect/UX gate. Layout is the "rendering this page would leak data" gate. Action/handler is the "writing data could happen even without rendering a page" gate. The last one is the security gate — the only one you cannot skip.

Code

Layer 1 — proxy·ts
// proxy.ts
export function proxy(request: NextRequest) {
  const session = request.cookies.get('session');
  if (!session && request.nextUrl.pathname.startsWith('/app')) {
    return NextResponse.redirect(new URL('/login', request.url));
  }
  return NextResponse.next();
}
Layer 2 — layout·tsx
// app/(app)/layout.tsx
import { auth } from '@/auth';
import { redirect } from 'next/navigation';

export default async function AppLayout({ children }: { children: React.ReactNode }) {
  const session = await auth();
  if (!session) redirect('/login');
  return (
    <>
      <AppNav user={session.user} />
      {children}
    </>
  );
}
Layer 3 — every action verifies·ts
'use server';
import { auth } from '@/auth';

export async function deleteAccount() {
  const session = await auth();
  if (!session) throw new Error('Unauthorized');
  await db.user.delete({ where: { id: session.user.id } });
}

External links

Exercise

Pick a sensitive action in your app (delete account, transfer money, etc.). Add explicit auth checks at proxy, layout, and action level. Try to bypass each layer and confirm the deepest one stops you.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.