Next.js(미들웨어)
Next.js 미들웨어는 엣지에서 실행됩니다. 즉, 요청이 표준 API 경로, 서버 작업 또는 데이터베이스에 도달하기 전에 사용자와 매우 가까운 곳에서 실행됩니다. 이는 악성 트래픽을 삭제하기 위한 최적의 초크 포인트입니다.
미들웨어
이 구현은 기본 'NextRequest' 개체를 활용하여 클라이언트 IP를 안정적으로 추출합니다. 경량 Edge Runtime을 사용하여 ProxyTracer API를 가져오고 500ms 제한 시간을 엄격하게 적용하여 페이지 로드가 매우 빠른 속도로 유지되도록 합니다.
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export async function middleware(request: NextRequest) {
// 1. IP 추출 (Next.js는 Vercel/Edge에서 request.ip를 안전하게 채웁니다)
// 커스텀 리버스 프록시 뒤에서 자체 호스팅하는 경우 헤더로 폴백
const ip = request.ip || request.headers.get('x-forwarded-for')?.split(',')[0].trim()
// 로컬 개발 환경인 경우 통과
if (!ip || ip === '127.0.0.1' || ip === '::1') {
return NextResponse.next()
}
try {
// 2. 엄격한 타임아웃과 함께 기본 fetch를 사용하여 ProxyTracer API 쿼리
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를 초과하면 연결을 끊습니다
})
if (ptResponse.ok) {
const data = await ptResponse.json()
// 3. 프록시/VPN이 감지되면 즉시 연결 차단
if (data.proxy === true) {
return NextResponse.json(
{ error: "Access Denied: VPN or Proxy detected." },
{ status: 403 }
)
}
}
} catch (error) {
// Fail open: API 시간 초과 시 가동 시간 보장을 위해 트래픽 허용
console.error('ProxyTracer API Error:', error)
}
// 4. 정상 트래픽인 경우 요청된 페이지 또는 API 라우트로 전달
return NextResponse.next()
}
// 5. Matcher 구성
// 민감한 라우트에 이 미들웨어를 적용하거나, 모든 경로를 보호하기 위해 전역으로 유지
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 배포 참고: Vercel에 배포하는 경우 'request.ip'가 실제 클라이언트 IP임이 보장됩니다. 사용자 지정 Node/Docker 인프라에서 자체 호스팅하지 않는 한 프록시 헤더를 수동으로 구문 분석할 필요가 없습니다.
최종 수정일: