Java로 개발을 하다 보면 로그인 이력을 남기거나 하는 상황에 Client IP를 데이터베이스에 Insert 하는 로직을 만들어야 하는 경우가 생길 수 있다.. 크게 2가지의 방법이 존재하는데 하나하나 설명해볼까 한다.
1. InetAddress
import java.net.InetAddress;
import java.net.UnknownHostException;
public static String getClientIP(HttpServletRequest req) throws UnknownHostException {
InetAddress clientAddress = InetAddress.getLocalHost();
ip = clientAddress.getHostName() + "/" + address.getHostAddress();
return ip;
}
허나 위의 방식으로 개발을 하게 되면 로컬 서버에서 접속을 하였을 때 나의 Client IP는 잘 찾지만 서버에 배포하게 되면 Proxy 서버를 거치게 되면서 배포한 서버 IP가 Client로 잡혀 배포한 서버 IP가 나오게 된다.
위의 문제점에 대한 대안으로 Client IP를 구하는 표준
2. request.getHeader("X-Forwarded-For");
public static String getClientIp(HttpServletRequest req) {
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Real-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-RealIP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("REMOTE_ADDR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
사실상 Client IP를 구하는 표준이다. Client가 서버에 request를 보낼 때 request 헤더에 "X-Forwarded-For" 키로
IP를 담아 보내게 된다.
이것도 문제점이라고 할 수도 있는... 한 가지 문제점이 존재하는데 서버에 배포된 서비스에서는 Client IP를 잘 찾지만
로컬에서 접속을 하였을 때 IPv4 또는 IPv6으로 Client IP를 "0:0:0:0:0:0:0:1"을 잡게 되거나 "127.0.0.1"를 잡게 되는 상황이 생기게 된다.
그러므로 가장 이상적으로 IP를 찾는 방법은...
3. 혼합..
import java.net.InetAddress;
import java.net.UnknownHostException;
public static String getClientIp(HttpServletRequest request) throws UnknownHostException {
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Real-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-RealIP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("REMOTE_ADDR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
if(ip.equals("0:0:0:0:0:0:0:1") || ip.equals("127.0.0.1"))
{
InetAddress address = InetAddress.getLocalHost();
ip = address.getHostName() + "/" + address.getHostAddress();
}
return ip;
}
1번과 2번의 방법을 적절히 혼합하여 사용하는 방법이 될 수 있겠다.
3번과 같이 적절히 혼합하여 getClientIP라는 메서드로 모듈화 하여 사용하게 된다면
로컬 서버로 접속하였을 때와 배포된 서버로 접속하였을 경우 적절하게 Client IP를 찾아올 수 있을 것이다...
'프로그래밍 > Java' 카테고리의 다른 글
ModelMapper란? (0) | 2023.07.12 |
---|---|
[Java] StringTokenizer에 대해 알아보자~ (0) | 2022.08.09 |
String vs (StringBuffer vs StringBuilder) (0) | 2022.06.07 |
Java에서 문자열 앞뒤 공백 제거 (0) | 2022.05.31 |
++i vs i++ (0) | 2022.05.18 |
댓글