如何在servlet中获取客户端的远程地址?

gra*_*l8d 66 proxy client servlets ip-address

有什么办法可以让客户端的原始IP地址进入服务器吗?我可以使用request.getRemoteAddr(),但我似乎总是得到代理或Web服务器的IP.

我想知道客户端用来连接我的IP地址.无论如何我能得到它吗?

Far*_*uti 104

试试这个:

public static String getClientIpAddr(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;  
    }  
Run Code Online (Sandbox Code Playgroud)

  • X-Forwarded-For可以包含多个IP地址. (2认同)

Boz*_*zho 10

request.getRemoteAddr()就是这样.您的代理似乎更改了源IP.当某些代理执行此操作时,他们会在某些自定义http标头中添加原始IP.使用request.getHeaderNames()request.getHeaders(name)打印所有这些内容以查看是否没有任何感兴趣的内容.喜欢X-CLIENT-IP(做一个,但他们看起来像这样)

  • 你的意思是request.getHeaderNames()? (2认同)

cra*_*ter 7

由于这通常是一个部署问题,而不是应用程序问题,另一种方法是适当地配置应用程序容器。配置完成后,容器会负责检查相应的标头,您的应用程序将继续使用request.getRemoteAddr().

例如,在 Tomcat 中,您可以使用Remote IP Valve。我假设大多数应用服务器都具有类似的功能。

容器还可以了解您的前端负载均衡器是否正在终止 SSL 连接,通过 HTTP 将请求转发到应用服务器。当您的应用程序需要为其自身生成 URL 时,这一点很重要。


Ali*_*emi 5

我用过的最好的解决方案

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;      
} 
Run Code Online (Sandbox Code Playgroud)


whi*_*row 5

为什么不使用像这样更优雅的解决方案?

private static final List<String> IP_HEADERS = Arrays.asList("X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR");

public static String getClientIpAddr(HttpServletRequest request) {
    return IP_HEADERS.stream()
        .map(request::getHeader)
        .filter(Objects::nonNull)
        .filter(ip -> !ip.isEmpty() && !ip.equalsIgnoreCase("unknown"))
        .findFirst()
        .orElseGet(request::getRemoteAddr);
}
Run Code Online (Sandbox Code Playgroud)

删除重复的代码!