Java 클 라 이언 트 사용자 의 실제 IP 주소 가 져 오기
역방향 프 록 시 를 사용 하면http://192.168.1.1102046 / 의 URL 역방향 에이전트 는http://www.javapeixun.com.cn / 의 URL 을 사용 할 때 request. getRemoteAddr () 방법 으로 얻 은 IP 주 소 는 클 라 이언 트 의 실제 IP 가 아 닌 127.0.0.1 또는 192.168.1.110 입 니 다.
프 록 시 를 거 친 후에 클 라 이언 트 와 서비스 사이 에 중간 층 이 추가 되 었 기 때문에 서버 는 클 라 이언 트 의 IP 를 직접 받 을 수 없고 서버 측 응용 도 요청 한 주 소 를 클 라 이언 트 에 게 직접 전달 할 수 없습니다.그러나 전송 요청 한 HTTP 헤더 정보 에 X - FORWARDED - FOR 정보 가 추가 되 었 습 니 다.기 존의 클 라 이언 트 IP 주소 와 원래 클 라 이언 트 가 요청 한 서버 주 소 를 추적 합 니 다.우리 가 방문 할 때http://www.javapeixun.com.cn / index. jsp / 시, 사실 우리 브 라 우 저가 서버 에 있 는 index. jsp 파일 에 진정 으로 접근 한 것 이 아니 라, 프 록 시 서버 에서 먼저 접근 한 것 입 니 다http://192.168.1.110: 2046 / index. jsp, 프 록 시 서버 는 방문 한 결 과 를 브 라 우 저 에 게 되 돌려 줍 니 다. 프 록 시 서버 가 index. jsp 를 방문 하 는 것 이기 때 문 입 니 다.그래서 index. jsp 에서 request. getRemoteAddr () 의 방법 으로 얻 은 IP 는 실제 프 록 시 서버 의 주소 이지 클 라 이언 트 의 IP 주소 가 아 닙 니 다.
따라서 클 라 이언 트 의 실제 IP 주 소 를 얻 는 방법 1:
public String getRemortIP(HttpServletRequest request) {
if (request.getHeader("x-forwarded-for") == null) {
return request.getRemoteAddr();
}
return request.getHeader("x-forwarded-for");
}
근 데 내 가 방문 하면http://www.5a520.cn / index. jsp / 시 되 돌아 오 는 IP 주 소 는 항상 알 수 없 으 며 위 에서 보 여 준 127.0.0.1 또는 192.168.1.110 이 아 닙 니 다. 제 가 방문 한 것 입 니 다.http://192.168.1.110: 2046 / index. jsp 시 클 라 이언 트 의 실제 IP 주 소 를 되 돌려 주 고 검증 하 는 방법 을 썼 습 니 다.원인 은 Squid 에서 나 왔 다.squid. conf 의 배합 파일 forwardfor 항목 의 기본 값 은 on 입 니 다. forwardfor 설정 off: X - Forward - for: unknown
따라서 클 라 이언 트 의 실제 IP 주 소 를 얻 는 방법 2:
import javax.servlet.http.HttpServletRequest;
/**
*
*
* IP
* @author X-rapido
*
*/
public class CusAccessObjectUtil {
/**
* IP , request.getRemoteAddr(); IP ,
* : http://developer.51cto.com/art/201111/305181.htm
*
* , ,X-Forwarded-For , IP , IP ?
* X-Forwarded-For unknown IP 。
*
* :X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130,
* 192.168.1.100
*
* IP : 192.168.1.110
*
* @param request
* @return
*/
public static String getIpAddress(HttpServletRequest request) {
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.getRemoteAddr();
}
return ip;
}
}
그러나 다단 계 역방향 에이 전 트 를 통과 하면 X - Forward - For 의 값 은 하나 가 아니 라 Ip 값 입 니 다. 도대체 어느 것 이 진정한 사용자 측의 실제 IP 입 니까?
정 답 은 X - Forward - For 에서 최초 로 알 수 없 는 유효한 IP 문자열 을 가 져 오 는 것 입 니 다.
예 를 들 어 X - Forward - For: 192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100 사용자 의 실제 IP 는 192.168.1.110 이다.
위의 간단 한 IP 획득 을 제외 하고 일반 회 사 는 내부 네트워크 외부 네트워크 판단 을 할 것 이다. 전체 예 는 다음 과 같다.
import javax.servlet.http.HttpServletRequest;
/**
* IP
* @author xudongdong
*
*/
public class IpUtil {
/**
*
*/
private IpUtil() {
}
/**
* IP
* getRealIP
* @param request req
* @return ip
*/
@Deprecated
public static String getClinetIpByReq(HttpServletRequest request) {
// ip
String clientIp = request.getHeader("x-forwarded-for");
if (clientIp == null || clientIp.length() == 0 || "unknown".equalsIgnoreCase(clientIp)) {
clientIp = request.getHeader("Proxy-Client-IP");
}
if (clientIp == null || clientIp.length() == 0 || "unknown".equalsIgnoreCase(clientIp)) {
clientIp = request.getHeader("WL-Proxy-Client-IP");
}
if (clientIp == null || clientIp.length() == 0 || "unknown".equalsIgnoreCase(clientIp)) {
clientIp = request.getRemoteAddr();
}
/*
* ip , ip.
*/
String sIP = null;
if (clientIp != null && !clientIp.contains("unknown") && clientIp.indexOf(",") > 0) {
String[] ipsz = clientIp.split(",");
for (String anIpsz : ipsz) {
if (!isInnerIP(anIpsz.trim())) {
sIP = anIpsz.trim();
break;
}
}
/*
* ip ip, ip.
*/
if (null == sIP) {
sIP = ipsz[0].trim();
}
clientIp = sIP;
}
if (clientIp != null && clientIp.contains("unknown")){
clientIp =clientIp.replaceAll("unknown,", "");
clientIp = clientIp.trim();
}
if ("".equals(clientIp) || null == clientIp){
clientIp = "127.0.0.1";
}
return clientIp;
}
/**
* IP
* @param ipAddress ip
* @return
*/
public static boolean isInnerIP(String ipAddress) {
boolean isInnerIp;
long ipNum = getIpNum(ipAddress);
/**
IP:A 10.0.0.0-10.255.255.255
B 172.16.0.0-172.31.255.255
C 192.168.0.0-192.168.255.255
, 127
**/
long aBegin = getIpNum("10.0.0.0");
long aEnd = getIpNum("10.255.255.255");
long bBegin = getIpNum("172.16.0.0");
long bEnd = getIpNum("172.31.255.255");
long cBegin = getIpNum("192.168.0.0");
long cEnd = getIpNum("192.168.255.255");
isInnerIp = isInner(ipNum, aBegin, aEnd) || isInner(ipNum, bBegin, bEnd) || isInner(ipNum, cBegin, cEnd)
|| ipAddress.equals("127.0.0.1");
return isInnerIp;
}
private static long getIpNum(String ipAddress) {
String[] ip = ipAddress.split("\\.");
long a = Integer.parseInt(ip[0]);
long b = Integer.parseInt(ip[1]);
long c = Integer.parseInt(ip[2]);
long d = Integer.parseInt(ip[3]);
return a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d;
}
private static boolean isInner(long userIp, long begin, long end) {
return (userIp >= begin) && (userIp <= end);
}
public static String getRealIP(HttpServletRequest request){
// ip
String clientIp = request.getHeader("x-forwarded-for");
if (clientIp == null || clientIp.length() == 0 || "unknown".equalsIgnoreCase(clientIp)) {
clientIp = request.getRemoteAddr();
}
String[] clientIps = clientIp.split(",");
if(clientIps.length <= 1) return clientIp.trim();
// CDN
if(isComefromCDN(request)){
if(clientIps.length>=2) return clientIps[clientIps.length-2].trim();
}
return clientIps[clientIps.length-1].trim();
}
private static boolean isComefromCDN(HttpServletRequest request) {
String host = request.getHeader("host");
return host.contains("www.189.cn") ||host.contains("shouji.189.cn") || host.contains(
"image2.chinatelecom-ec.com") || host.contains(
"image1.chinatelecom-ec.com");
}
}
원본 주소: http://www.ibloger.net/article/144.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.