This commit is contained in:
2025-12-09 17:02:27 +09:00
parent 26f8e1dab2
commit 83127da569
275 changed files with 139682 additions and 1 deletions

View File

@@ -0,0 +1,52 @@
import { Request } from 'express';
/**
* 클라이언트의 실제 IP 주소를 추출합니다.
*
* @description
* Proxy, Load Balancer, CDN 뒤에 있어도 실제 클라이언트 IP를 정확하게 가져옵니다.
* 다음 순서로 IP를 확인합니다:
* 1. X-Forwarded-For 헤더 (Proxy/Load Balancer)
* 2. X-Real-IP 헤더 (Nginx)
* 3. req.ip (Express 기본)
* 4. req.socket.remoteAddress (직접 연결)
* 5. 'unknown' (IP를 찾을 수 없는 경우)
*
* @param req - Express Request 객체
* @returns 클라이언트 IP 주소
*
* @example
* const ip = getClientIp(req);
* console.log(ip); // '203.123.45.67' or 'unknown'
*/
export function getClientIp(req: Request): string {
// 1. X-Forwarded-For 헤더 확인 (Proxy/Load Balancer 환경)
// 형식: "client IP, proxy1 IP, proxy2 IP"
const forwardedFor = req.headers['x-forwarded-for'];
if (forwardedFor) {
// 배열이면 첫 번째 요소, 문자열이면 콤마로 split
const ips = Array.isArray(forwardedFor)
? forwardedFor[0]
: forwardedFor.split(',')[0];
return ips.trim();
}
// 2. X-Real-IP 헤더 확인 (Nginx 환경)
const realIp = req.headers['x-real-ip'];
if (realIp && typeof realIp === 'string') {
return realIp.trim();
}
// 3. Express가 제공하는 req.ip
if (req.ip) {
return req.ip;
}
// 4. Socket의 remoteAddress
if (req.socket?.remoteAddress) {
return req.socket.remoteAddress;
}
// 5. IP를 찾을 수 없는 경우
return 'unknown';
}