Next.js (Middleware)
Next.js Middleware draait aan de Edge, wat betekent dat het extreem dicht bij je gebruikers wordt uitgevoerd voordat een verzoek ooit je standaard API-routes, server actions of database bereikt. Dit is het optimale knooppunt om schadelijk verkeer vroegtijdig te weren.
De Middleware
Deze implementatie maakt gebruik van het native NextRequest-object om het client-IP betrouwbaar te extraheren. Het roept de ProxyTracer API aan via de lichtgewicht Edge Runtime en handhaaft een strikte timeout van 500ms om te garanderen dat je laadtijden razendsnel blijven.
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export async function middleware(request: NextRequest) {
// 1. Extraheer het IP-adres (Next.js vult request.ip veilig in op Vercel/Edge)
// Val terug op headers bij self-hosting achter een aangepaste reverse proxy
const ip = request.ip || request.headers.get('x-forwarded-for')?.split(',')[0].trim()
// Doorlaten bij lokale ontwikkeling
if (!ip || ip === '127.0.0.1' || ip === '::1') {
return NextResponse.next()
}
try {
// 2. Raadpleeg de ProxyTracer API met native fetch en een strikte 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) // Verbreekt de verbinding als het > 500ms duurt
})
if (ptResponse.ok) {
const data = await ptResponse.json()
// 3. Verbreek de verbinding onmiddellijk als er een proxy/VPN wordt gedetecteerd
if (data.proxy === true) {
return NextResponse.json(
{ error: "Access Denied: VPN or Proxy detected." },
{ status: 403 }
)
}
}
} catch (error) {
// Fail open: Als de API een timeout geeft, laat verkeer door om uptime te garanderen
console.error('ProxyTracer API Error:', error)
}
// 4. Verkeer is schoon, ga door naar de opgevraagde pagina of API-route
return NextResponse.next()
}
// 5. Configureer de Matcher
// Pas deze middleware toe op gevoelige routes, of laat deze globaal om alles te beschermen
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-opmerking: Als je op Vercel deployt, is request.ip gegarandeerd het werkelijke client-IP. Je hoeft proxy-headers niet handmatig te parsen, tenzij je self-host op een custom Node/Docker-infrastructuur.