Next.js (Middleware)
Next.js Middleware runs at the Edge, meaning it executes incredibly close to your users before a request ever hits your standard API routes, server actions, or database. This is the optimal choke point for dropping malicious traffic.
The Middleware
This implementation utilizes the native NextRequest object to reliably extract the client IP. It fetches the ProxyTracer API using the lightweight Edge Runtime and strictly enforces a 500ms timeout to ensure your page loads remain lightning fast.
// 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).*)',
],
}Vercel Deployment Note: If you are deploying on Vercel, request.ip is guaranteed to be the true client IP. You do not need to manually parse proxy headers unless you are self-hosting on a custom Node/Docker infrastructure.
Last updated on