blog
Segurança

Como proteger rotas no Next.js

Middleware, Server Components e API Routes — 3 formas de proteger seu app.

hidden: true

Proteger rotas no Next.js

Seu app tem páginas que só usuários logados devem ver. Veja como proteger.

1. Middleware (recomendado)

Intercepta TODAS as requests antes de chegar na página:

// middleware.ts (na raiz do projeto)
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
 
export function middleware(request: NextRequest) {
  const token = request.cookies.get("session");
 
  // Rotas protegidas
  if (request.nextUrl.pathname.startsWith("/dashboard")) {
    if (!token) {
      return NextResponse.redirect(new URL("/login", request.url));
    }
  }
 
  // Redirecionar logados para fora do /login
  if (request.nextUrl.pathname === "/login" && token) {
    return NextResponse.redirect(new URL("/dashboard", request.url));
  }
 
  return NextResponse.next();
}
 
export const config = {
  matcher: ["/dashboard/:path*", "/login"],
};

2. Server Components

Verificar auth dentro do componente:

// app/dashboard/page.tsx
import { getServerSession } from "next-auth"
import { redirect } from "next/navigation"
 
export default async function Dashboard() {
  const session = await getServerSession()
 
  if (!session) {
    redirect("/login")
  }
 
  return (
    <div>
      <h1>Bem-vindo, {session.user.name}!</h1>
    </div>
  )
}

3. API Routes

// app/api/users/route.ts
import { getServerSession } from "next-auth";
 
export async function GET() {
  const session = await getServerSession();
 
  if (!session) {
    return Response.json({ error: "Não autorizado" }, { status: 401 });
  }
 
  const users = await db.user.findMany();
  return Response.json(users);
}

Layout protegido

Proteja um grupo inteiro de páginas via layout:

// app/dashboard/layout.tsx
import { getServerSession } from "next-auth"
import { redirect } from "next/navigation"
 
export default async function DashboardLayout({ children }) {
  const session = await getServerSession()
  if (!session) redirect("/login")
 
  return (
    <div>
      <nav>Dashboard Nav</nav>
      {children}
    </div>
  )
}

Todas as páginas dentro de /dashboard/* são protegidas automaticamente.

Com Supabase

import { createClient } from "@/lib/supabase/server"
import { redirect } from "next/navigation"
 
export default async function ProtectedPage() {
  const supabase = await createClient()
  const { data: { user } } = await supabase.auth.getUser()
 
  if (!user) redirect("/login")
 
  return <h1>Olá, {user.email}</h1>
}

Dica

Use middleware para proteção global (redirecionar para login). Use Server Components para lógica específica (mostrar dados do usuário).