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.