Careeroza
Protecting Pages and Actions
Pages
Call auth() in a Server Component. It reads the session cookie for this request.
// app/account/page.tsx
import { redirect } from 'next/navigation';
import { auth } from '@/auth';
export default async function AccountPage() {
const session = await auth();
if (!session?.user) redirect('/login?next=/account');
return <h1>Hi {session.user.name}</h1>;
}Route Handlers and Server Actions
// app/api/orders/route.ts
import { auth } from '@/auth';
import { prisma } from '@/lib/prisma';
export async function GET() {
const session = await auth();
if (!session?.user) return Response.json({ error: 'Unauthorized' }, { status: 401 });
const orders = await prisma.order.findMany({ where: { userId: session.user.id } });
return Response.json(orders);
}// app/account/actions.ts
'use server';
import { auth } from '@/auth';
export async function updatePhone(phone: string) {
const session = await auth();
if (!session?.user) throw new Error('Unauthorized'); // actions are public endpoints!
await prisma.user.update({ where: { id: session.user.id }, data: { phone } });
}Note: Checking auth only in middleware or only in the layout is not enough. Layouts do not re-run on every navigation, and Server Actions can be called directly. Check close to the data.
Middleware as a First Gate
// middleware.ts (proxy.ts in Next.js 16)
export { auth as middleware } from '@/auth';
export const config = { matcher: ['/account/:path*', '/admin/:path*', '/checkout/:path*'] };// auth.ts — decide in the "authorized" callback
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [/* ... */],
callbacks: {
authorized({ auth, request }) {
const isAdminPath = request.nextUrl.pathname.startsWith('/admin');
if (isAdminPath) return auth?.user?.role === 'admin';
return !!auth?.user; // false -> redirect to the sign-in page
},
},
});