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,其余步骤如上。
  • request.getHeader("X-Real-IP") 获取的ip地址始终固定是:115.1.2.3
  • request.getHeader("X-Forwarded-For")获取的结果固定是: 115.1.2.3,10.x.x.x
    • 结果是一个字符串,第一个值与X-Real-IP值一样。
    • 第二个值一直在动态变化
  • request.getRemoteAddr()获取的结果固定是: 192.168.1.10

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

这方法正确吗?

大概看了下这方法逻辑就是先获取请求体的realIp,获取不到才去获取forward啥的ip。

那我这边为什么始终能获取到realIp且始终固定1个值,我已经模拟了2个用户来登录了。

那不是起不到不同ip的效果了吗。

所以我怀疑是不是这个115.1.2.3是网关还是哪台服务器的ip。

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

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

得到了以下结论:

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

在jax的告诫"去掉这块代码,让其为空则不禁用,否则内网锁定ip,且很可能是用户微服务集群2台的ip,那就都不能登录了"下,我删掉了这块代码。

且最终咨询了运维之后发现这个固定的192.168.1.10正是开发环境的K8S地址!那确实不能返回!

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

那我明白了,我连公司vpn及我公司电脑其实都是连的公司wifi,所以最终请求发出去都是走的公司网关,此网关不是web项目的网关!

所以最终地址都一致。那这么看满足需求,1个人连的1个wifi,不能连续输错密码5次否则ip禁用,用其他方式连wifi也一样。

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

所以“X-Forwarded-For”第二个值开始则是代理服务器的地址。

咨询了jax和让运维看了后发现是k8s的一些容器的地址。

只是这个地址为什么一直变jax也很奇怪。我测了下是每次都在变。

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

“X-Forwarded-For”的字面意思是“为谁而转发”,形式上和“Via”差不多,也是每经过一个代理节点就会在字段里追加一个信息。但“Via”追加的是代理主机名(或者域名),而“X-Forwarded-For”追加的是请求方的 IP 地址。所以,在字段里最左边的 IP 地址就是客户端的地址。

“X-Real-IP”是另一种获取客户端真实 IP 的手段,它的作用很简单,就是记录客户端 IP 地址,没有中间的代理信息,相当于是“X-Forwarded-For”的简化版。如果客户端和源服务器之间只有一个代理,那么这两个字段的值就是相同的。

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

    /**
     * 获取真实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 "";
        }
    }

总结

到此这篇关于springboot获取真实ip地址的文章就介绍到这了,更多相关springboot获取真实ip内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • springboot 获取访问接口的请求的IP地址的实现

    工具类: import javax.servlet.http.HttpServletRequest; import java.net.InetAddress; import java.net.UnknownHostException; /** * @Author : JCccc * @CreateTime : 2018-11-23 * @Description : * @Point: Keep a good mood **/ public class IpUtil { public static

  • springboot获取真实ip地址的方法实例

    需求是用户在登录时,密码输错了5次以上要将这个ip禁用,所以如题,我需要在登录接口代码中获得这次请求的原始ip地址.禁用ip的逻辑已经写好了,目前痛点是获取ip地址,也正是这块代码让我被领导叼了. 既然项目一般都是走nginx和网关代理,那肯定得百度了,于是百度的代码如下: /** * 获取ip地址 * * @param request * @return */ public String getIpAddr(HttpServletRequest request) { String ip = r

  • C#获取真实IP地址实现方法

    本文实例讲述了C#获取真实IP地址实现方法,分享给大家供大家参考.具体实现方法如下: 通常来说,大家获取用户IP地址常用的方法是: 复制代码 代码如下: string IpAddress = ""; if((HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]!=null && HttpContext.Current.Request.ServerVariables[&q

  • PHP 获取客户端 IP 地址的方法实例代码

    先来了解一个变量的含义: $_SERVER['REMOTE_ADDR']:浏览当前页面的用户计算机的ip地址 $_SERVER['HTTP_CLIENT_IP']:客户端的ip $_SERVER['HTTP_X_FORWARDED_FOR']:浏览当前页面的用户计算机的网关 $_SERVER['HTTP_X_REAL_IP']:nginx 代理模式下,获取客户端真实IP /** * 获取客户端IP地址 */ function real_ip() { $ip = $_SERVER['REMOTE_

  • C#获取真实IP地址(IP转为长整形、判断是否内网IP的方法)

    今天查看登录日志,发现http_x_forwarded_for获取到的ip地址有些是内网ip地址,有些则是公网和内网ip地址一起获取到,用逗号分隔开,日志截图如下: 之前获取ip地址的C#代码如下: 复制代码 代码如下: /// <summary>     /// C#获取客户端真实IP地址     /// </summary>     /// <returns></returns>     public static string GetIP()    

  • jsp获取客户端IP地址的方法

    本文实例讲述了jsp获取客户端IP地址的方法.分享给大家供大家参考,具体如下: public static String getIpAddr(HttpServletRequest request) { String ip = request.getHeader("X-Forwarded-For"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request

  • JSP 获取真实IP地址的代码

    但是在通过了 Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了.如果使用了反向代理软件,用 request.getRemoteAddr()方法获取的IP地址是:127.0.0.1或 192.168.1.110,而并不是客户端的真实IP. 经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的 IP,服务器端应用也无法直接通过转发请求的地址返回给客户端.但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息.用以跟踪原有的客户端

  • python使用Flask框架获取用户IP地址的方法

    本文实例讲述了python使用Flask框架获取用户IP地址的方法.分享给大家供大家参考.具体如下: 下面的代码包含了html页面和python代码,非常详细,如果你正使用Flask,也可以学习一下最基本的Flask使用方法. python代码如下: from flask import Flask, render_template, request # Initialize the Flask application app = Flask(__name__) # Default route,

  • Python使用django获取用户IP地址的方法

    本文实例讲述了Python使用django获取用户IP地址的方法.分享给大家供大家参考.具体如下: 函数实现: def get_client_ip(request): try: real_ip = request.META['HTTP_X_FORWARDED_FOR'] regip = real_ip.split(",")[0] except: try: regip = request.META['REMOTE_ADDR'] except: regip = "" r

  • JS简单获取客户端IP地址的方法【调用搜狐接口】

    本文实例讲述了JS简单获取客户端IP地址的方法.分享给大家供大家参考,具体如下: <!doctype html> <html> <head> <meta charset="utf-8"> <title>使用搜狐接口获取客户端IP地址</title> </head> <body> <script src="http://pv.sohu.com/cityjson?ie=utf-8

  • jQuery获取访问者IP地址的方法(基于新浪API与QQ查询接口)

    本文实例讲述了jQuery获取访问者IP地址的方法.分享给大家供大家参考,具体如下: <script type="text/javascript" src="jquery.min.js"></script> <script type="text/javascript"> $(document).ready(function(){ //通过调用新浪IP地址库接口查询用户当前所在国家.省份.城市.运营商信息 $.g

随机推荐