Next.js (Middleware)
Next.js Middleware wird am Edge ausgeführt, was bedeutet, dass sie in unmittelbarer Nähe Ihrer Nutzer abläuft, bevor eine Anfrage jemals Ihre Standard-API-Routen, Server Actions oder die Datenbank erreicht. Dies ist der optimale Kontrollpunkt, um bösartigen Datenverkehr abzuweisen.
Die Middleware
Diese Implementierung nutzt das native NextRequest-Objekt, um die Client-IP zuverlässig zu extrahieren. Sie ruft die ProxyTracer-API in der leichtgewichtigen Edge Runtime ab und erzwingt ein striktes 500-ms-Timeout, um sicherzustellen, dass Ihre Seitenladezeiten blitzschnell bleiben.
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export async function middleware(request: NextRequest) {
// 1. IP extrahieren (Next.js befüllt request.ip auf Vercel/Edge sicher)
// Fallback auf Header beim Self-Hosting hinter einem benutzerdefinierten Reverse-Proxy
const ip = request.ip || request.headers.get('x-forwarded-for')?.split(',')[0].trim()
// Bei lokaler Entwicklung durchleiten
if (!ip || ip === '127.0.0.1' || ip === '::1') {
return NextResponse.next()
}
try {
// 2. ProxyTracer-API mit nativem fetch und einem strikten Timeout abfragen
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) // Bricht die Verbindung ab, wenn sie > 500ms dauert
})
if (ptResponse.ok) {
const data = await ptResponse.json()
// 3. Verbindung sofort trennen, falls ein Proxy/VPN erkannt wird
if (data.proxy === true) {
return NextResponse.json(
{ error: "Access Denied: VPN or Proxy detected." },
{ status: 403 }
)
}
}
} catch (error) {
// Fail-Open: Wenn die API ein Timeout hat, Traffic erlauben, um die Verfügbarkeit sicherzustellen
console.error('ProxyTracer API Error:', error)
}
// 4. Traffic ist sauber, weiter zur angeforderten Seite oder API-Route
return NextResponse.next()
}
// 5. Matcher konfigurieren
// Diese Middleware auf sensible Routen anwenden oder global belassen, um alles zu schützen
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).*)',
],
}Vercel-Deployment-Hinweis: Wenn Sie auf Vercel bereitstellen, ist garantiert, dass request.ip die echte Client-IP ist. Sie müssen Proxy-Header nicht manuell parsen, es sei denn, Sie betreiben eine selbst gehostete benutzerdefinierte Node/Docker-Infrastruktur.