Skip to Content

Next.js (Middleware)

O Middleware do Next.js é executado na Edge, o que significa que roda incrivelmente perto dos seus usuários antes que uma requisição chegue às suas rotas de API padrão, server actions ou banco de dados. Este é o ponto ideal para descartar tráfego malicioso.

O Middleware

Esta implementação utiliza o objeto nativo NextRequest para extrair o IP do cliente com confiabilidade. Ela consulta a API do ProxyTracer usando o leve Edge Runtime e impõe estritamente um timeout de 500ms para garantir que os carregamentos de página continuem ultrarrápidos.

// middleware.ts import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' export async function middleware(request: NextRequest) { // 1. Extraia o IP (o Next.js preenche request.ip com segurança na Vercel/Edge) // Fallback para cabeçalhos se auto-hospedado atrás de um proxy reverso personalizado const ip = request.ip || request.headers.get('x-forwarded-for')?.split(',')[0].trim() // Liberar se for ambiente de desenvolvimento local if (!ip || ip === '127.0.0.1' || ip === '::1') { return NextResponse.next() } try { // 2. Consulte a API do ProxyTracer usando fetch nativo com um timeout rigoroso const ptResponse = await fetch(`https://api.proxytracer.com/v1/check/${ip}`, { method: 'GET', headers: { 'Authorization': `Bearer ${process.env.PROXYTRACER_API_KEY}` }, signal: AbortSignal.timeout(500) // Encerra a conexão se levar mais de 500ms }) if (ptResponse.ok) { const data = await ptResponse.json() // 3. Encerre a conexão imediatamente se um proxy/VPN for detectado if (data.proxy === true) { return NextResponse.json( { error: "Access Denied: VPN or Proxy detected." }, { status: 403 } ) } } } catch (error) { // Fail-open: Se a API expirar por timeout, permita o tráfego para garantir a disponibilidade console.error('ProxyTracer API Error:', error) } // 4. O tráfego é legítimo, prossiga para a página ou rota de API solicitada return NextResponse.next() } // 5. Configure o Matcher // Aplique este middleware a rotas sensíveis ou mantenha-o global para proteger tudo export const config = { matcher: [ /* * Match all request paths except for the ones starting with: * - _next/static (static files) * - _next/image (image optimization files) * - favicon.ico (favicon file) */ '/((?!_next/static|_next/image|favicon.ico).*)', ], }

Nota de Implantação na Vercel: Se você estiver implantando na Vercel, o request.ip é garantido como o IP real do cliente. Você não precisa analisar manualmente cabeçalhos de proxy, a menos que esteja auto-hospedando em uma infraestrutura personalizada com Node/Docker.

Última atualização