HttpRequestHeader로부터 사용자 요청 IP(Internet protocol) 가져오는 방법
프로젝트를 하게 되면 IP Whitelist 등의 목적으로 인해 사용자의 요청 IP를 가져와야 하는 경우가 있습니다.
IP란 무엇인지 간단하게 살펴보고, HttpServletRequest로부터 사용자의 요청 IP를 가져오는 코드를 함께 살펴보겠습니다.
(IP 가져오는 부분의 코드만 살펴보실 분은 내용을 아래로 조금만 스킵해주시길 바랍니다.)
IP(Internet protocol)란,
IP 통신에 필요한 고유 주소를 말하며, 인터넷에 연결된 통신 기능이 제공되는 모든 장치들(컴퓨터, 스마트폰 등)이 서로 통신을 하기 위해 필요한 식별이 가능한 고유 번호입니다.
스마트폰으로 예를 들면 스마트폰끼리 통화를 할 수 있는 고유한 전화번호라고 생각할 수 있습니다.
IP주소는 IPv4, IPv6 두 가지 종류가 있는데, 일반적으로 이야기하는 IP주소는 IPv4를 말합니다.
IPv4(IP version 4)는 전 세계적으로 사용된 첫 번째 인터넷 프로토콜이며, 주소는 8 bits씩 4자리로 총 32 bits(4 bytes)입니다.
IPv4는 0~2^32개(약 43억 개)의 주소를 가질 수 있는데, 세계적으로 인터넷 사용자 수가 급증하면서 현재는 IANA로부터의 신규 IPv4 할당이 중단된 상태라고 합니다.
ex) 2606:2800:1000:0001:25C8:0000:1946:0220
IPv6는 이러한 IPv4 주소의 부족으로 인해 고안된 차기 주소 체계이며, 네트워크 속도의 측면에서나 보안적인 측면에서 모두 뛰어나지만 현재 기존의 주소체계를 변경하는데 드는 비용 문제로 인해 조금씩 적용되고 있는 추세라고 합니다.
IPv6(IP version 6)는 기존의 주소체계보다 훨씬 큰 128 bits 크기를 가지며, 16 bits씩 8자리로 구성되었으며, 각 자리는 콜론 : 으로 구분합니다.
Client IP 가져오기,
public static String getClientIp(HttpServletRequest request) {
String clientIp = null;
boolean isIpInHeader = false;
List<String> headerList = new ArrayList<>();
headerList.add("X-Forwarded-For");
headerList.add("HTTP_CLIENT_IP");
headerList.add("HTTP_X_FORWARDED_FOR");
headerList.add("HTTP_X_FORWARDED");
headerList.add("HTTP_FORWARDED_FOR");
headerList.add("HTTP_FORWARDED");
headerList.add("Proxy-Client-IP");
headerList.add("WL-Proxy-Client-IP");
headerList.add("HTTP_VIA");
headerList.add("IPV6_ADR");
for (String header : headerList) {
clientIp = request.getHeader(header);
if (StringUtils.hasText(clientIp) && !clientIp.equals("unknown")) {
isIpInHeader = true;
break;
}
}
if (!isIpInHeader) {
clientIp = request.getRemoteAddr();
}
return clientIp;
}
보통 HttpServletRequest의 getRemoteAddr() 메서드를 통해 IP를 가져오는데, 이때 WAS(Web Application Server) 서버 앞에 프록시 서버나 로드 밸런싱 서버 등의 다른 서버가 존재하는 경우, 클라이언트의 IP가 아닌 해당 서버의 IP를 가지고 오게 됩니다.
이때 클라이언트의 IP는 예시 코드처럼 Header에 담긴 정보를 통해 가져올 수 있습니다.
(X-Forwarded-For (XFF) - HTTP 프록시나 로드 밸런서를 통해 웹 서버에 접속하는 클라이언트의 원 IP 주소를 식별하는 표준 헤더)
'Programming > Java' 카테고리의 다른 글
Java 위도 경도에 따른 거리 계산(내 주변 반경) (2) | 2022.08.03 |
---|---|
@MappedSuperclass 조금 다르게 사용해보기 (0) | 2022.07.18 |
LocalDateTime Jackson 직렬화 오류, 두 가지 해결 방법 (0) | 2022.06.04 |
Java QR코드 생성 (Image 출력 및 파일저장) (5) | 2022.05.28 |
Java - Future Interface 비동기적 연산 작업을 위한 인터페이스 (2) | 2022.04.04 |