-1

我正在使用以下代码(从另一篇文章复制 -如何在 servlet 中获取客户端的远程地址?)来获取客户端 IP 地址以及代理服务器(部署在 PCF 中的 SpringBoot Appln)。

  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;
  }

request.getHeader("X-Forwarded-For"); /request.getRemoteAddr(); (从本地运行时)给出预期的结果。我真的不明白其他条件的用途。

  1. 在所有情况下,我都看到“未知”.equalsIgnoreCase(IP) 被使用。但是当我尝试访问 request.getHeader("Proxy-Client-IP") 或任何垃圾字符串时,我得到了空值。当 HttpServletRequest getHeader 返回未知?这可以忽略吗?
  2. Proxy-Client-IP/HTTP_CLIENT_IP 有什么用。我猜它是用来单独获取客户端IP(没有代理服务器IP)的。它是特定于特定服务器的吗?如果是的话,哪个服务器。这可以在 Spring Boot 应用程序中忽略吗
  3. 我猜“WL-Proxy-Client-IP”是 WebLogic 特有的。这也可以忽略吗?
  4. 我相信 HTTP_ 前缀特定于 PHP(HTTP_X_FORWARDED_FOR 和 HTTP_CLIENT_IP。)在 SpringBoot 应用程序中是否有必要?
  5. 我觉得下面的代码足以获取客户端IP地址以及代理服务器(前提是我使用带有嵌入式tomcat的spring boot并将代码部署在PCF中)。能否请你确认?

    private static String getClientIpAddr(HttpServletRequest httpRequest)
    {
      String clientIp = httpRequest.getHeader("X-Forwarded-For");
    
      if (clientIp == null || clientIp.length() == 0)
      {
        clientIp = httpRequest.getRemoteAddr();
      }
      return clientIp;
    }
    
4

1 回答 1

1

你可能想要这样的东西。

public class HttpRequestHelper {

    private static final String[] HEADERS= {"X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR"};

    public static String getClientIpAddr(HttpServletRequest request) {
        for (String header : HEADERS) {
            String ip = request.getHeader(header);
            if (ip != null && ip.length() > 0) {                    
                return StringUtils.commaDelimitedListToStringArray(ip)[0];
            }
        }
        return request.getRemoteAddr();
    }    
}

这将尝试所有标题(按给定顺序),如果存在则返回。否则它将回退到request.getRemoteAddr(). 用更少的if语句达到同样的效果。

我还考虑了X-Forwarded-For标头中可能存在多个 IP 地址的情况。它将始终返回已解析数组中的第一个元素。

于 2018-08-14T07:06:12.330 回答