Next.js (Middleware)
Next.js Middleware'i Edge'de çalışır; yani bir istek standart API rotalarınıza, server action'larınıza veya veritabanınıza ulaşmadan önce kullanıcılarınıza son derece yakın bir noktada yürütülür. Bu, kötü niyetli trafiği durdurmak için en uygun kontrol noktasıdır.
Middleware
Bu uygulama, istemci IP'sini güvenilir bir şekilde çıkarmak için yerel NextRequest nesnesini kullanır. Hafif Edge Runtime kullanarak ProxyTracer API'sini sorgular ve sayfa yüklemelerinizin ışık hızında kalmasını sağlamak için kesin bir 500 ms zaman aşımı uygular.
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export async function middleware(request: NextRequest) {
// 1. IP'yi çıkarın (Next.js, Vercel/Edge üzerinde request.ip değerini güvenli bir şekilde doldurur)
// Özel bir ters proxy arkasında kendi sunucunuzda barındırıyorsanız başlıklara geri dönün
const ip = request.ip || request.headers.get('x-forwarded-for')?.split(',')[0].trim()
// Yerel geliştirme ortamındaysa doğrudan geçirin
if (!ip || ip === '127.0.0.1' || ip === '::1') {
return NextResponse.next()
}
try {
// 2. Kesin bir zaman aşımı ile yerel fetch kullanarak ProxyTracer API'sini sorgulayın
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) // 500ms'den uzun sürerse bağlantıyı keser
})
if (ptResponse.ok) {
const data = await ptResponse.json()
// 3. Proxy/VPN tespit edilirse bağlantıyı derhal kesin
if (data.proxy === true) {
return NextResponse.json(
{ error: "Access Denied: VPN or Proxy detected." },
{ status: 403 }
)
}
}
} catch (error) {
// Fail open: API zaman aşımına uğrarsa çalışma süresini korumak için trafiğe izin verin
console.error('ProxyTracer API Error:', error)
}
// 4. Trafik temiz, istenen sayfaya veya API rotasına devam edin
return NextResponse.next()
}
// 5. Matcher'ı yapılandırın
// Bu middleware'i hassas rotalara uygulayın veya her şeyi korumak için global bırakın
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 Dağıtım Notu: Vercel üzerinde dağıtım yapıyorsanız, request.ip değerinin gerçek istemci IP'si olacağı garanti edilir. Özel bir Node/Docker altyapısında kendi sunucunuzda barındırmadığınız sürece proxy başlıklarını manuel olarak ayrıştırmanıza gerek yoktur.