Skip to Content

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 인프라에서 자체 호스팅하지 않는 한 프록시 헤더를 수동으로 구문 분석할 필요가 없습니다.

최종 수정일: