关于java:获取客户端的IP地址

Getting IP address of client

本问题已经有最佳答案,请猛点这里访问。

我正在使用JSP,Servlet(容器:Glassfish)开发Web应用程序,需要在其中获取客户端IP Address

我正在获取客户的IP地址,因为我只想允许在办公室内的计算机上访问某些页面(例如客户维护表单),所以我想限制对办公室外部那些页面的访问。

以下是我到目前为止的代码:

方式1

1
2
String ipAddress =  request.getRemoteAddr();
System.out.println("IP Address:"+ipAddress);

方式2

1
2
3
4
5
6
7
8
String ipAddress=null;
String getWay = request.getHeader("VIA");   // Gateway
ipAddress = request.getHeader("X-FORWARDED-FOR");   // proxy
if(ipAddress==null)
{
    ipAddress = request.getRemoteAddr();
}
System.out.println("IP Address:"+ipAddress);

每次重新启动计算机时,上述代码都会给我different IP Address(关机->启动或重新启动)。

我得到IP6像:

1
fe80:0:0:0:20ca:1776:f5ff:ff15%13

让我知道这段代码有什么问题吗?


正如@martin和此答案所解释的,它很复杂。没有防弹方法来获取客户端的IP地址。

最好的办法是尝试解析"X-Forwarded-For"并依赖request.getRemoteAddr();

1
2
3
4
5
6
7
8
9
10
11
public static String getClientIpAddress(HttpServletRequest request) {
    String xForwardedForHeader = request.getHeader("X-Forwarded-For");
    if (xForwardedForHeader == null) {
        return request.getRemoteAddr();
    } else {
        // As of https://en.wikipedia.org/wiki/X-Forwarded-For
        // The general format of the field is: X-Forwarded-For: client, proxy1, proxy2 ...
        // we only want the client
        return new StringTokenizer(xForwardedForHeader,",").nextToken().trim();
    }
}


我使用以下静态帮助器方法来检索客户端的IP:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public static String getClientIpAddr(HttpServletRequest request) {  
    String ip = request.getHeader("X-Forwarded-For");  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("Proxy-Client-IP");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("WL-Proxy-Client-IP");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_X_FORWARDED_FOR");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_X_FORWARDED");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_X_CLUSTER_CLIENT_IP");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_CLIENT_IP");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_FORWARDED_FOR");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_FORWARDED");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("HTTP_VIA");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getHeader("REMOTE_ADDR");  
    }  
    if (ip == null || ip.length() == 0 || ip.equalsIgnoreCase("unknown")) {  
        ip = request.getRemoteAddr();  
    }  
    return ip;  
}


我喜欢这样,你可以试试看

1
2
3
4
5
6
7
8
9
10
11
12
13
public String getIpAddr(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.getRemoteAddr();      
   }      
   return ip;      
}


如basZero所述,应检查X-Forwarded-For的逗号。 (请参阅:http://en.wikipedia.org/wiki/X-Forwarded-For)。该字段的一般格式为:
X-Forwarded-For:clientIP,proxy1,proxy2 ...等。因此,我们将看到如下所示:X-FORWARDED-FOR:129.77.168.62,129.77.63.62。


我相信这与您的网络配置有关。 Servlet只是给您找到的地址。

我可以提出两种解决方法。首先尝试使用IPV4。看到这个SO答案

另外,请尝试使用request.getRemoteHost()方法获取计算机的名称。当然,名称独立于它们映射到的IP。

我仍然认为您应该与基础架构人员讨论这一问题。