java获取HttpServletRequest 的客户端ip

  常见的问题,记录操作日志中发现,getRemoteAddr取到的客户端的ip地址不是真实的ip,需要解析请求头中的信息获取正确ip。

public static String getIpAddress(HttpServletRequest request) {

        String ip = request.getHeader("X-Forwarded-For");

        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            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.getRemoteAddr();
            }
        } else {
            String[] ips = ip.split(",");
            for (int index = 0; index < ips.length; index++) {
                String strIp = ips[index];
                if (!(UNKNOWN.equalsIgnoreCase(strIp))) {
                    ip = strIp;
                    break;
                }
            }
        }
        return ip;
    }

  查了下,对应的header头解释如下。

  x-forwarded-for只是代理的其中一种,最早Squid 引入,还有很多其他的字段

  Proxy-Client-IP:使用apache代理

  WL-Proxy-Client-IP:使用weblogic时

  HTTP_CLIENT_IP和HTTP_X_FORWARDED_FOR:有一些代理

  X-Real-IP:Nginx代理

  如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串Ip值,取X-Forwarded-For中第一个非unknown的有效IP字符串。 

  每经过一个代理做一次转发,X-Forwarded_For就会在后面追加一个代理IP,并且以转发顺序排序。

posted on 2021-04-05 17:22  lnlvinso  阅读(939)  评论(0编辑  收藏  举报