Capítulo 295 de 456

Authentication

Core Idea

Autenticação no Pages Router se divide em três conceitos: Authentication (verificar identidade), Session Management (manter estado entre requests) e Authorization (controlar acesso); a doc recomenda usar uma lib de auth pronta em vez de solução 100% custom.

Key Concepts

  • Authentication: form de login envia POST pra API Route (/api/auth/login), que chama o provider (signIn('credentials', ...)).
  • Stateless sessions: dados/token na cookie do browser, enviado a cada request; mais simples, exige httpOnly+secure corretos.
  • Database sessions: dados de sessão no banco, browser só guarda o ID de sessão criptografado; mais seguro, mais complexo.
  • Optimistic checks (Proxy): checagem rápida lendo só a cookie (sem hit no banco) pra redirecionar usuário não autenticado; não deve ser a única defesa.
  • Secure checks (DAL): checagem real contra sessão no banco, feita o mais perto possível da fonte de dados (Data Access Layer).
  • DTO (Data Transfer Objects): retornar só os dados necessários ao client, nunca o objeto completo do banco.

Code Examples

import { serialize } from 'cookie'
import { encrypt } from '@/app/lib/session'

export default function handler(req: NextApiRequest, res: NextApiResponse) {
  const sessionData = req.body
  const encryptedSessionData = encrypt(sessionData)
  const cookie = serialize('session', encryptedSessionData, {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    maxAge: 60 * 60 * 24 * 7,
    path: '/',
  })
  res.setHeader('Set-Cookie', cookie)
  res.status(200).json({ message: 'Successfully set cookie!' })
}
  • O que demonstra: cookie de sessão stateless com httpOnly+secure+maxAge corretos.
export default async function proxy(req: NextRequest) {
  const path = req.nextUrl.pathname
  const isProtectedRoute = protectedRoutes.includes(path)
  const cookie = (await cookies()).get('session')?.value
  const session = await decrypt(cookie)
  if (isProtectedRoute && !session?.userId) {
    return NextResponse.redirect(new URL('/login', req.nextUrl))
  }
  return NextResponse.next()
}
  • O que demonstra: checagem otimista (só cookie, sem banco) no Proxy pra redirecionar cedo.

Reference Tables

Tipo de sessãoOnde vive o dadoSegurançaComplexidade
StatelessCookie do browserMenor (se mal implementada)Baixa
DatabaseBanco, browser só tem IDMaiorAlta
Tipo de check de autorizaçãoFonteUso
OptimisticCookieUI rápida, redirect em Proxy
SecureBanco (via DAL)Dados sensíveis, ações reais

Anti-patterns

  • Usar Proxy como única defesa: Proxy roda inclusive em rotas prefetched; checagem real de autorização deve ficar na DAL, perto da fonte de dados.
  • Fazer query de banco dentro do Proxy: gera problema de performance, já que Proxy roda em toda rota, inclusive prefetch.
  • Retornar objeto de usuário completo pro client: usar DTO pra vazar só o necessário.

Key Takeaways

  1. Prefira lib de auth (Auth0, Clerk, NextAuth.js, Supabase etc.) a implementação custom completa.
  2. Proxy serve pra checagem otimista e redirect cedo; a autorização de verdade vai na Data Access Layer.
  3. Cookie de sessão sempre com httpOnly e secure em produção.
  4. API Routes que expõem dado sensível precisam checar sessão E role antes de processar.

Connects To

  • ch298 Content Security Policy: Proxy também é o mecanismo usado pra injetar nonce de CSP.