Skip to Content
DocumentationEdgeNext.js Middleware

Next.js (Middleware)

Next.js Middleware se ejecuta en el Edge, lo que significa que corre muy cerca de tus usuarios antes de que una solicitud llegue a tus rutas API estándar, server actions o base de datos. Este es el punto de control óptimo para detener tráfico malicioso.

El Middleware

Esta implementación utiliza el objeto nativo NextRequest para extraer con fiabilidad la IP del cliente. Consulta la API de ProxyTracer utilizando el ligero Edge Runtime y aplica estrictamente un tiempo de espera de 500ms para asegurar que tus páginas carguen a toda velocidad.

// middleware.ts import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' export async function middleware(request: NextRequest) { // 1. Extract the IP (Next.js populates request.ip securely on Vercel/Edge) // Fallback to headers if self-hosting behind a custom reverse proxy const ip = request.ip || request.headers.get('x-forwarded-for')?.split(',')[0].trim() // Pass through if local development if (!ip || ip === '127.0.0.1' || ip === '::1') { return NextResponse.next() } try { // 2. Query ProxyTracer API using native fetch with a strict timeout 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) // Drops the connection if it takes > 500ms }) if (ptResponse.ok) { const data = await ptResponse.json() // 3. Drop the connection immediately if a proxy/VPN is detected if (data.proxy === true) { return NextResponse.json( { error: "Access Denied: VPN or Proxy detected." }, { status: 403 } ) } } } catch (error) { // Fail open: If the API times out, allow traffic to ensure uptime console.error('ProxyTracer API Error:', error) } // 4. Traffic is clean, proceed to the requested page or API route return NextResponse.next() } // 5. Configure the Matcher // Apply this middleware to sensitive routes, or leave it global to protect everything 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 Despliegue en Vercel: Si estás desplegando en Vercel, está garantizado que request.ip sea la IP real del cliente. No necesitas analizar manualmente los encabezados de proxy a menos que alojes tu infraestructura Node/Docker en servidores propios.

Last updated on