java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > springboot获取请求ip方法

springboot之如何获取请求ip方法

作者:Yweir

这篇文章主要介绍了springboot之如何获取请求ip方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

springboot获取请求ip方法

/**
     * 获取ip
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ipAddress = null;
        try {
            ipAddress = request.getHeader("x-forwarded-for");
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
                ipAddress = request.getRemoteAddr();
                if (ipAddress.equals("127.0.0.1")) {
                    // 根据网卡取本机配置的IP
                    InetAddress inet = null;
                    try {
                        inet = InetAddress.getLocalHost();
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    }
                    ipAddress = inet.getHostAddress();
                }
            }
            // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
            if (ipAddress != null && ipAddress.length() > 15) {
                // "***.***.***.***".length()
                // = 15
                if (ipAddress.indexOf(",") > 0) {
                    ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
                }
            }
        } catch (Exception e) {
            ipAddress="";
        }
        return ipAddress;
    }

springboot获取真实ip地址

需求是用户在登录时,密码输错了5次以上要将这个ip禁用,所以如题,我需要在登录接口代码中获得这次请求的原始ip地址。

禁用ip的逻辑已经写好了,目前痛点是获取ip地址,也正是这块代码让我被领导叼了。

既然项目一般都是走nginx和网关代理,那肯定得百度了,于是百度的代码如下:

    /**
     * 获取ip地址
     *
     * @param request
     * @return
     */
    public String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("X-Real-IP");
        if (ip != null && !"".equals(ip) && !"unknown".equalsIgnoreCase(ip)) {
            return ip;
        }
        ip = request.getHeader("X-Forwarded-For");
        if (ip != null && !"".equals(ip) && !"unknown".equalsIgnoreCase(ip)) {
            int index = ip.indexOf(',');
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        } else {
            return request.getRemoteAddr();
        }
    }

然后我模拟2个用户测了一下(测试结果为化名):

公司电脑本地启服务,注册到公司开发环境的nacos上,通过网关调用此登录接口

用另一台电脑连公司vpn,其余步骤如上。

1.request.getHeader("X-Real-IP") 获取的ip地址始终固定是:115.1.2.3

2.request.getHeader("X-Forwarded-For")获取的结果固定是: 115.1.2.3,10.x.x.x

3.request.getRemoteAddr()获取的结果固定是: 192.168.1.10

所以我很疑惑,首先看了下公司日志过滤器那块代码也正是用的上面的方法,完全一样。那么说明是一样的。

这方法正确吗?

为什么X-Forwarded-For的第一个值与realIp一样且第二个值一直变。

且第二个值代表什么ip,为什么一直在变。此刻我怀疑是不是就是我2台电脑的无线网动态变化的ip,那么这么看我得取这第二个值了。

带着这些疑惑,真的很菜的我继续百度+咨询公司运维+最终询问领导。

得到了以下结论:

1.首先明确request.getRemoteAddr()这块不能要。一看就是内网ip,不然直接锁死了。

2.realIp固定的115.1.2.3问了运维大哥后知道了是真实ip地址!不是内网地址!且是公司的网关地址。

3.“X-Forwarded-For”第一个值与其realIo一样应该是我只有1个代理。这边也确实只有Nginx代理了。

所以原来方法是对的,只去获取forward的第一个值!

所以最终改造后的代码为:

    /**
     * 获取真实ip地址,不返回内网地址
     *
     * @param request
     * @return
     */
    public String getIpAddr(HttpServletRequest request) {
        //目前则是网关ip
        String ip = request.getHeader("X-Real-IP");
        if (ip != null && !"".equals(ip) && !"unknown".equalsIgnoreCase(ip)) {
            return ip;
        }
        ip = request.getHeader("X-Forwarded-For");
        if (ip != null && !"".equals(ip) && !"unknown".equalsIgnoreCase(ip)) {
            int index = ip.indexOf(',');
            if (index != -1) {
                //只获取第一个值
                return ip.substring(0, index);
            } else {
                return ip;
            }
        } else {
            //取不到真实ip则返回空,不能返回内网地址。
            return "";
        }
    }

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文