▹ 주요 언어/JAVA

HttpServletRequest에서 클라이언트의 IP 주소 추출하기

기록원장 2024. 11. 1. 01:27
반응형

HttpServletRequest에서 클라이언트의 IP주소 추출하는 로직이다.

 

서버가 프록시나 로드 밸런서를 통해 클라이언트 요청을 받을 경우, 클라이언트의 실제 IP 주소는 여러 HTTP 헤더에 설정될 수 있다.

아래 소스코드는 HttpServletRequest의 헤더("X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR", "X-Real-IP", "X-RealIP")를 순서대로 검사하여 가장 먼저 발견되는 유효한 IP 주소를 반환하고, 만약 모든 헤더에서 유효한 IP를 찾지 못하면 getRemoteAddr()로부터 IP를 가져오는 처리를 한다.

헤더 이름 설명
getHeader("X-Forwarded-For")
가장 널리 사용되는 헤더이다.
클라이언트의 IP 주소와, 여러 프록시 서버를 경유한 경우 모든 경유지의 IP 주소를 포함한다.
이 경우, 값은 쉼표로 구분되며 가장 왼쪽의 IP가 클라이언트의 실제 IP이다.
getHeader("Proxy-Client-IP") 일부 프록시 서버(특히 Apache와 같은 서버)에서 클라이언트의 IP 주소를 저장하기 위해 사용하는 헤더이다.
getHeader("WL-Proxy-Client-IP") WebLogic 서버가 클라이언트의 IP를 전달하기 위해 사용하는 헤더이다.
getHeader("HTTP_CLIENT_IP") HTTP 요청의 헤더에서 클라이언트의 IP 주소를 전달하기 위해 사용되는 헤더이다.
요청을 보내는 클라이언트의 IP 주소를 포함하고 있다.
getHeader("HTTP_X_FORWARDED_FOR") X-Forwarded-For와 유사한 역할을 하는 헤더로, 클라이언트의 IP와 경유지의 IP를 저장한다.
X-Forwarded-For와 마찬가지로 가장 왼쪽의 IP가 클라이언트의 실제 IP이다.
getHeader("X-Real-IP")
getHeader("X-RealIP")
Nginx와 같은 웹 서버에서 클라이언트의 실제 IP 주소를 저장하기 위해 사용되는 헤더이다.
getRemoteAddr() 클라이언트의 IP 주소를 반환한다.
단 요청이 도착한 소켓의 원격 주소를 기반으로 하기 때문에 프록시를 거치는 경우에는 클라이언트 IP가 아닌, 마지막 프록시의 IP를 반환할 수 있다

 

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;

public String getAceessIpAddress(HttpServletRequest request) {
        String accessIp = request.getHeader("X-Forwarded-For");
        
        if (Objects.isNull(accessIp) || accessIp.length() == 0 || "unknown".equalsIgnoreCase(accessIp)) {
            accessIp = request.getHeader("Proxy-Client-IP");
        }
        if (Objects.isNull(accessIp) || accessIp.length() == 0 || "unknown".equalsIgnoreCase(accessIp)) {
            accessIp = request.getHeader("WL-Proxy-Client-IP");
        }
        if (Objects.isNull(accessIp) || accessIp.length() == 0 || "unknown".equalsIgnoreCase(accessIp)) {
            accessIp = request.getHeader("HTTP_CLIENT_IP");
        }
        if (Objects.isNull(accessIp) || accessIp.length() == 0 || "unknown".equalsIgnoreCase(accessIp)) {
            accessIp = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (Objects.isNull(accessIp) || accessIp.length() == 0 || "unknown".equalsIgnoreCase(accessIp)) {
            accessIp = request.getHeader("X-Real-IP");
        }
        if (Objects.isNull(accessIp) || accessIp.length() == 0 || "unknown".equalsIgnoreCase(accessIp)) {
            accessIp = request.getHeader("X-RealIP");
        }
        if (Objects.isNull(accessIp) || accessIp.length() == 0 || "unknown".equalsIgnoreCase(accessIp)) {
            accessIp = request.getRemoteAddr();
        }
        return accessIp;
    }

 


글 내용 중 잘못된 부분이 있거나, 첨부하실 내용이 있으시면 댓글로 남겨주세요. 공부하는데 많은 도움이 됩니다.
-- 기억의 유효기간은 생각보다 짧다. --
반응형