精华内容
下载资源
问答
  • Java获取客户端IP

    2017-09-12 11:03:36
    Java获取客户端IP

    在开发工作中,我们常常需要获取客户端的IP。一般获取客户端的IP地址的方法是:request.getRemoteAddr();但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。

    原因:由于在客户端和服务之间增加了中间代理,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接通过转发请求的地址返回给客户端。

    现在图示代理上网和IP的关系:

     

    第一种情况:不通过代理上网,服务器端拿到真实IP

     

    第二种情况:通过代理服务器如:Nginx,Squid等一层代理或多层代理上网,如下图:

     

    需要注意的是X-Forwarded-For和X-Real-IP都不是http的正式协议头,而是squid等反向代理软件最早引入的,之所以resin能拿到,是因为NGINX里一般缺省都会这么配置转发的http请求:

    location / {

             proxy_pass       http://yourdomain.com;

             proxy_set_header   Host             $host;

             proxy_set_header   X-Real-IP        $remote_addr;

             proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

             },从X-Forwarded-For的定义来看,ips[0]才是原始客户端ip,如果这个都不是,那拿第二个就更不靠谱了,我们平时检验的时候,可能是直接在内网挂代理去访问的,跟外面网友访问经过的网络路径不一样,后面不停添加的是经过的每一层代理ip才对,下面举例说明;

    request.getRemoteAddr() 192.168.239.196

    request.getHeader("X-Forwarded-For") 58.63.227.162, 192.168.237.178, 192.168.238.218

    request.getHeader("X-Real-IP") 192.168.238.218

    所以访问的流程应该是这样,客户端58.63.227.162发出请求,经过192.168.237.178, 192.168.238.218两层转发,到了192.168.239.196这台NGINX上,NGINX就把X-Real-IP头设成了自己看到的remote_addr,也就是直接发给到他的192.168.238.218,这时候resin收到这个包,对resin来说直接发给他的remote_addr就是NGINX的ip,也就是192.168.239.196,那么resin里面的request.getRemoteAddr()就是192.168.239.196,那么在resin里拿最原始的ip逻辑(也就是拿能够知道的最外层的ip)应该是这样:

                如果XFF不为空,拿XFF的左边第一个

                如果XFF为空,拿XRI

                如果XRI为空,只能拿request.getRemoteAddr(),也就是只能拿到最直接发给他的机器ip了,

    其他都不可考究,参考代码如下:

    第一种代码:

    复制代码
          /**
          * 从Request对象中获得客户端IP,处理了HTTP代理服务器和Nginx的反向代理截取了ip
          * @param request
          * @return ip
          */
        public static String getLocalIp(HttpServletRequest request) {
            String remoteAddr = request.getRemoteAddr();
            String forwarded = request.getHeader("X-Forwarded-For");
            String realIp = request.getHeader("X-Real-IP");
    
            String ip = null;
            if (realIp == null) {
                if (forwarded == null) {
                    ip = remoteAddr;
                } else {
                    ip = remoteAddr + "/" + forwarded.split(",")[0];
                }
            } else {
                if (realIp.equals(forwarded)) {
                    ip = realIp;
                } else {
                    if(forwarded != null){
                        forwarded = forwarded.split(",")[0];
                    }
                    ip = realIp + "/" + forwarded;
                }
            }
            return ip;
        }
    复制代码

    第二种代码:

    复制代码
     1      public static String getIp(HttpServletRequest request) {
     2         String remoteAddr = request.getRemoteAddr();
     3         String forwarded = request.getHeader("X-Forwarded-For");
     4         String realIp = request.getHeader("X-Real-IP");
     5 
     6         String ip = null;
     7         if (realIp == null) {
     8             if (forwarded == null) {
     9                 ip = remoteAddr;
    10             } else {
    11                 ip = remoteAddr + "/" + forwarded;
    12             }
    13         } else {
    14             if (realIp.equals(forwarded)) {
    15                 ip = realIp;
    16             } else {
    17                 ip = realIp + "/" + forwarded.replaceAll(", " + realIp, "");
    18             }
    19         }
    20         return ip;
    21     }
    复制代码

    第三种代码:

    复制代码
     1        public static String getIp2(HttpServletRequest request) {
     2            String ip = request.getHeader("X-Forwarded-For");
     3            if(StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)){
     4                //多次反向代理后会有多个ip值,第一个ip才是真实ip
     5                int index = ip.indexOf(",");
     6                if(index != -1){
     7                    return ip.substring(0,index);
     8                }else{
     9                    return ip;
    10                }
    11            }
    12            ip = request.getHeader("X-Real-IP");
    13            if(StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)){
    14                return ip;
    15            }
    16            return request.getRemoteAddr();
    17        }
    复制代码整理网友的材料,最后有源码,亲测能解决所有java获取IP真实地址的问题

    整理的这里:

    1、
    链接1 

    2、链接2

    JSP里,获取客户端的IP地址的方法是:
    request.getRemoteAddr()
    ,这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。

    如果使用了反向代理软件,将
    http://192.168.1.110:2046/
    的URL反向代理为
    http://www.javapeixun.com.cn /
    的URL时,用
    request.getRemoteAddr()
    方法获取的IP地址是:127.0.0.1 或 192.168.1.110,而并不是客户端的真实IP。

    ISAPI过滤器也会对request对象进行再包装,附加一些WLS要用的头信息。实际的iisforward附加头如下:

    [code]WL-Proxy-Client-IP=211.161.1.239  
    Proxy-Client-IP=211.161.1.239  
    X-Forwarded-For=211.161.1.239  
    WL-Proxy-Client-Keysize=   
    WL-Proxy-Client-Secretkeysize=   
    X-WebLogic-Request-ClusterInfo=true  
    X-WebLogic-KeepAliveSecs=30  
    X-WebLogic-Force-JVMID=-327089098  
    WL-Proxy-SSL=false


    经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息。用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。当我们访问
    http://www.javapeixun.com.cn /index.jsp/
    时,其实并不是我们浏览器真正访问到了服务器上的index.jsp文件,而是先由代理服务器去访问
    http://192.168.1.110:2046/index.jsp
    ,代理服务器再将访问到的结果返回给我们的浏览器,因为是代理服务器去访问index.jsp的,所以index.jsp中通过
    request.getRemoteAddr()
    的方法获取的IP实际上是代理服务器的地址,并不是客户端的IP地址。

    于是可得出获得客户端真实IP地址的方法一:

    [code]public String getRemortIP(HttpServletRequest request) { 
      if (request.getHeader("x-forwarded-for") == null) { 
       return request.getRemoteAddr(); 
      } 
      return request.getHeader("x-forwarded-for"); 
     }


    可是当我访
    问http://www.5a520.cn /index.jsp/
    时,返回的IP地址始终是unknown,也并不是如上所示的127.0.0.1 或 192.168.1.110了,而我访问
    http://192.168.1.110:2046/index.jsp
    时,则能返回客户端的真实IP地址,写了个方法去验证。原因出在了Squid上。squid.conf 的配制文件 forwarded_for 项默认是为on,如果 forwarded_for 设成了 off  则:
    X-Forwarded-For: unknown


    于是可得出获得客户端真实IP地址的方法二:

    [code]public String getIpAddr(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.getRemoteAddr(); 
           } 
           return ip; 
       }


    可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值,究竟哪个才是真正的用户端的真实IP呢?

    答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。

    如:X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100用户真实IP为: 192.168.1.110

    以上方法还不行的话就采用如下方法:

    [code]/** 
         * 获取当前网络ip 
         * @param request 
         * @return 
         */  
        public String getIpAddr(HttpServletRequest request){  
            String 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") || ipAddress.equals("0:0:0:0:0: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(","));  
                    }  
                }  
                return ipAddress;   
        }

     

    	
    	/**
    	 * 获取当前客户端IP地址
    	 * @param request
    	 * @return
    	 */
    	public static String getRemoteAddress(HttpServletRequest request){
    		    String ip = request.getHeader("x-forwarded-for"); 
    	        if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {  
    	            // 多次反向代理后会有多个ip值,第一个ip才是真实ip
    	            if( ip.indexOf(",")!=-1 ){
    	                ip = ip.split(",")[0];
    	            }
    	        }  
    	        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();  
    	        } 
    	        return ip;
    	}

    展开全文
  • java获取客户端ip

    2018-07-24 20:27:00
    java获取客户端ip  Java获取IP地址:如果使用了反向代理软件,request.getRemoteAddr()获取到的是代理的ip,并不是客户端的ip。  经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到...

    java获取客户端ip

      Java获取IP地址:如果使用了反向代理软件,request.getRemoteAddr()获取到的是代理的ip,并不是客户端的ip。

      经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的IP,服务器端应用

      也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR

      信息用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。

     1  /**
     2      * 获取请求ip地址
     3      * @param request
     4      * @return
     5      */
     6     public static String getIpAddress(HttpServletRequest request) {
     7         String ip = request.getHeader("x-forwarded-for");
     8         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
     9             ip = request.getHeader("Proxy-Client-IP");
    10         }
    11         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    12             ip = request.getHeader("WL-Proxy-Client-IP");
    13         }
    14         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    15             ip = request.getHeader("HTTP_CLIENT_IP");
    16         }
    17         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    18             ip = request.getHeader("HTTP_X_FORWARDED_FOR");
    19         }
    20         if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
    21             ip = request.getRemoteAddr();
    22         }
    23         // 如果是多级代理,那么取第一个ip为客户ip
    24         /*if (ip != null && ip.indexOf(",") != -1) {
    25             ip = ip.substring(ip.lastIndexOf(",") + 1, ip.length()).trim();
    26         }*/
    27         return ip;
    28     }

     

    转载于:https://www.cnblogs.com/heqiyoujing/p/9362405.html

    展开全文
  • java 获取客户端IP

    2016-11-30 13:37:38
    Java获取客户端IP 在开发工作中,我们常常需要获取客户端的IP。一般获取客户端的IP地址的方法是:request.getRemoteAddr();但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。 原因:...

    Java获取客户端IP

    在开发工作中,我们常常需要获取客户端的IP。一般获取客户端的IP地址的方法是:request.getRemoteAddr();但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。

    原因:由于在客户端和服务之间增加了中间代理,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接通过转发请求的地址返回给客户端。

    现在图示代理上网和IP的关系:

     

    第一种情况:不通过代理上网,服务器端拿到真实IP

     

    第二种情况:通过代理服务器如:Nginx,Squid等一层代理或多层代理上网,如下图:

     

    需要注意的是X-Forwarded-For和X-Real-IP都不是http的正式协议头,而是squid等反向代理软件最早引入的,之所以resin能拿到,是因为NGINX里一般缺省都会这么配置转发的http请求:

    location / {

             proxy_pass       http://yourdomain.com;

             proxy_set_header   Host             $host;

             proxy_set_header   X-Real-IP        $remote_addr;

             proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

             },从X-Forwarded-For的定义来看,ips[0]才是原始客户端ip,如果这个都不是,那拿第二个就更不靠谱了,我们平时检验的时候,可能是直接在内网挂代理去访问的,跟外面网友访问经过的网络路径不一样,后面不停添加的是经过的每一层代理ip才对,下面举例说明;

    request.getRemoteAddr() 192.168.239.196

    request.getHeader("X-Forwarded-For") 58.63.227.162, 192.168.237.178, 192.168.238.218

    request.getHeader("X-Real-IP") 192.168.238.218

    所以访问的流程应该是这样,客户端58.63.227.162发出请求,经过192.168.237.178, 192.168.238.218两层转发,到了192.168.239.196这台NGINX上,NGINX就把X-Real-IP头设成了自己看到的remote_addr,也就是直接发给到他的192.168.238.218,这时候resin收到这个包,对resin来说直接发给他的remote_addr就是NGINX的ip,也就是192.168.239.196,那么resin里面的request.getRemoteAddr()就是192.168.239.196,那么在resin里拿最原始的ip逻辑(也就是拿能够知道的最外层的ip)应该是这样:

                如果XFF不为空,拿XFF的左边第一个

                如果XFF为空,拿XRI

                如果XRI为空,只能拿request.getRemoteAddr(),也就是只能拿到最直接发给他的机器ip了,

    其他都不可考究,参考代码如下:

    第一种代码:

    复制代码
          /**
          * 从Request对象中获得客户端IP,处理了HTTP代理服务器和Nginx的反向代理截取了ip
          * @param request
          * @return ip
          */
        public static String getLocalIp(HttpServletRequest request) {
            String remoteAddr = request.getRemoteAddr();
            String forwarded = request.getHeader("X-Forwarded-For");
            String realIp = request.getHeader("X-Real-IP");
    
            String ip = null;
            if (realIp == null) {
                if (forwarded == null) {
                    ip = remoteAddr;
                } else {
                    ip = remoteAddr + "/" + forwarded.split(",")[0];
                }
            } else {
                if (realIp.equals(forwarded)) {
                    ip = realIp;
                } else {
                    if(forwarded != null){
                        forwarded = forwarded.split(",")[0];
                    }
                    ip = realIp + "/" + forwarded;
                }
            }
            return ip;
        }
    复制代码

    第二种代码:

    复制代码
     1      public static String getIp(HttpServletRequest request) {
     2         String remoteAddr = request.getRemoteAddr();
     3         String forwarded = request.getHeader("X-Forwarded-For");
     4         String realIp = request.getHeader("X-Real-IP");
     5 
     6         String ip = null;
     7         if (realIp == null) {
     8             if (forwarded == null) {
     9                 ip = remoteAddr;
    10             } else {
    11                 ip = remoteAddr + "/" + forwarded;
    12             }
    13         } else {
    14             if (realIp.equals(forwarded)) {
    15                 ip = realIp;
    16             } else {
    17                 ip = realIp + "/" + forwarded.replaceAll(", " + realIp, "");
    18             }
    19         }
    20         return ip;
    21     }
    复制代码

    第三种代码:

    复制代码
     1        public static String getIp2(HttpServletRequest request) {
     2            String ip = request.getHeader("X-Forwarded-For");
     3            if(StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)){
     4                //多次反向代理后会有多个ip值,第一个ip才是真实ip
     5                int index = ip.indexOf(",");
     6                if(index != -1){
     7                    return ip.substring(0,index);
     8                }else{
     9                    return ip;
    10                }
    11            }
    12            ip = request.getHeader("X-Real-IP");
    13            if(StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)){
    14                return ip;
    15            }
    16            return request.getRemoteAddr();
    17        }
    复制代码

    第三种是最合适的,最清晰理解的

     

     

    转自: http://www.cnblogs.com/ITtangtang/p/3927768.html

    展开全文
  • java获取客户端IP

    2020-12-11 16:56:11
    一般来说,客户端IP通过request.getRemoteAddr()即可得到。但如果客户端通过代理访问后端时,request.getRemoteAddr()可能就不是客户端实际IP,此时需要通过一系列处理来得到客户端实际IP。 package com.origin.util...

    一般来说,客户端IP通过request.getRemoteAddr()即可得到。但如果客户端通过代理访问后端时,request.getRemoteAddr()可能就不是客户端实际IP,此时需要通过一系列处理来得到客户端实际IP。

    package com.origin.util;
    
    import lombok.extern.slf4j.Slf4j;
    
    import javax.servlet.http.HttpServletRequest;
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    /**
     * @Author xiye
     * @File HttpClientUtil
     * @Date 2020/12/10 16:11
     * @Desc 网络处理工具
     */
    @Slf4j
    public class HttpClientUtil {
        // 代理请求头名称集合。注意顺序
        public static final String[] IP_HEADER = new String[] {"X-Real-IP", "X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP"};
    
        /* ========================================================================================= */
        /**
         * @author  xiye
         * @date    2020/12/11  16:39
         * @param	request
         * @desc    获取客户端IP
         * @return  java.lang.String
         */
        public static String getRemoteAddress (HttpServletRequest request) {
            /*String client_ip = request.getHeader("x-forwarded-for");
            if(client_ip == null || client_ip.length() == 0 || "unknown".equalsIgnoreCase(client_ip)) {
                client_ip = request.getHeader("Proxy-Client-IP");
            }
            if(client_ip == null || client_ip.length() == 0 || "unknown".equalsIgnoreCase(client_ip)) {
                client_ip = request.getHeader("WL-Proxy-Client-IP");
            }*/
            String client_ip = null;
            int tag = 0;
            for (String header : IP_HEADER) {
                client_ip = request.getHeader(header);
                if (invalidIp(client_ip)) { tag ++; continue; }
                break;
            }
            if (tag < IP_HEADER.length) log.info("【{}代理IP】{}", IP_HEADER[tag], client_ip);
    
            if(invalidIp(client_ip)) {
                client_ip = request.getRemoteAddr();
                log.info("【无代理IP】{}", client_ip);
            }
            // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
            if(client_ip != null && client_ip.length() > 15){ //"***.***.***.***".length() = 15
                if(client_ip.indexOf(",") > 0){
                    client_ip = client_ip.substring(0,client_ip.indexOf(","));
                }
            }
            return client_ip;
        }
    
        /**
         * @author  xiye
         * @date    2020/12/11  15:25
         * @desc    获取内网IP
         * @return  java.lang.String
         */
        public static String getInnerIp () {
            try {
                return InetAddress.getLocalHost().getHostAddress();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
            return null;
        }
    
    
        /* ========================================= 公共 ================================================= */
        private static boolean invalidIp (String ip) {
            return ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip);
        }
    }
    
    

    参考1】nginx代理转发客户端IP:“X-Real-IP”、“X-Forwarded-For”

    展开全文
  • Java获取客户端Ip

    2017-09-04 10:08:52
    在开发工作中,我们常常需要获取客户端IP。一般获取客户端IP地址的方法是:request.getRemoteAddr();但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。 原因:由于在客户端和服务之间...
  • JAVA获取客户端IP

    2020-06-07 21:30:47
    ... ... * 获取访问者IP * 在一般情况下使用Request.getRemoteAddr()即可,但是经过nginx等反向代理软件后,这个方法会失效。 * 本方法先从Header中获取X-Real-IP,如果不存在再从X-Forwarded-F
  • JAVA 获取客户端 IP

    2019-05-05 13:12:34
    工具类: public static String getIpAddr(HttpServletRequest request) { String ipAddress = null; try { ipAddress = request.getHeader("x-forwarded-for"); if (ipAddress...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,530
精华内容 612
关键字:

java获取客户端ip

java 订阅