Java获取Nginx代理和非代理情况下真正IP地址

方法一:
public static String getIp(final HttpServletRequest request) {
        String ip;
        ip = request.getHeader("X-Forword-For");
        if (ip == null || ip.trim().equals("") || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.trim().equals("") || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.trim().equals("") || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.trim().equals("") || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.trim().equals("") || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }


        /* 多个路由时,取第一个非unknown的ip */
        if (ip != null && !ip.trim().equals("")) {
            if (ip.indexOf(',') > 0) {
                ip = ip.substring(0, ip.indexOf(','));
            }
            return ip;
        } else {
            return "0.0.0.0";
        }
    }


    其中第4行中的 “X-Forword-For” 为Nginx配置文件中配置,我的Nginx配置中为 X-Forword-For $proxy_add_x_forwarded_for;




方法二:


    public static final String _255 = "(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";
    public static final Pattern pattern = Pattern.compile("^(?:" + _255 + "\\.){3}" + _255 + "$");


    public static String getIpFromRequest(HttpServletRequest request) {
        String ip;
        boolean found = false;
        if ((ip = request.getHeader("X-Forword-For")) != null) {
            StrTokenizer tokenizer = new StrTokenizer(ip, ",");
            while (tokenizer.hasNext()) {
                ip = tokenizer.nextToken().trim();
                if (isIPv4Valid(ip) && !isIPv4Private(ip)) {
                    found = true;
                    break;
                }else if(isIPv4Valid(ip) && isIPv4Private(ip)){
                    log.info("###### 存在代理的内部IP");
                    return ip;
                }
            }
        }
        if (!found) {
            log.info("###### 无代理内部IP");
            ip = request.getRemoteAddr();
        }
        return ip;
    }


    public static boolean isIPv4Private(String ip) {
        log.info("###### 判断是否内部ip");
        long longIp = ip2long(ip);
        return (longIp >= ip2long("10.0.0.0") && longIp <= ip2long("10.255.255.255"))
                || (longIp >= ip2long("172.16.0.0") && longIp <= ip2long("172.31.255.255"))
                || longIp >= ip2long("192.168.0.0") && longIp <= ip2long("192.168.255.255");
    }


    public static boolean isIPv4Valid(String ip) {
        return pattern.matcher(ip).matches();
    }


    /**
     * 将127.0.0.1形式的IP地址转换成十进制整数,这里没有进行任何错误处理
     *
     * @param strIp
     * @return
     */
    public static long ip2long(final String strIp) {
        final long[] ip = new long[4];
        final int position1 = strIp.indexOf('.');
        final int position2 = strIp.indexOf('.', position1 + 1);
        final int position3 = strIp.indexOf('.', position2 + 1);


        ip[0] = Long.parseLong(strIp.substring(0, position1));
        ip[1] = Long.parseLong(strIp.substring(position1 + 1, position2));
        ip[2] = Long.parseLong(strIp.substring(position2 + 1, position3));
        ip[3] = Long.parseLong(strIp.substring(position3 + 1));


        return (ip[0] << 24) + (ip[1] << 16) + (ip[2] << 8) + ip[3];
    }


    其中第43行中的 "X-Forword-For" 同样为Nginx中配置内容。


    方法一和方法二都可以获取真实IP地址。(方法二中参考网上资源整理)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值