- Symptom
- A request to an /api/admin route with no cookie returns data or makes a changeThe admin page hides itself from strangers, but the API routes it calls still answer them
- Cause
- Route Handlers are public HTTP endpoints that any client can call directly. Hiding the admin page, or a check in the page component, does not protect the handlers it calls, and Next.js advises against relying on proxy (formerly middleware) alone for authentication and authorization.
- Fix
- Verify the session and the user's role at the top of every admin Route Handler, returning 401 when there is no session and 403 when the user is not an admin. Keep any proxy check as an extra layer, not the only one.
- Apply
import { NextResponse } from 'next/server' import { auth } from '@/lib/auth' export async function POST(request: Request) { const session = await auth() if (!session?.user) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }) } if (!session.user.isAdmin) { return NextResponse.json({ error: 'Forbidden' }, { status: 403 }) } // admin work here }- Affected
- Next.js Route Handlers and Pages Router API Routes that do admin or other privileged work
- Sources
Last verified 2026-10-27 · Confirmed by 0 builders