• 这种通过remoteip可以直接获取
  • 下面是通过代理上网的图例(其中代理服务器也可以是nginx)
  • 其中X-Forwarded-For和X-Real-IP都不是http的正式协议头,而是squid等反向代理软件最早引入的。如果连XFF第一个都不是客户ip,那么第二个就更不靠谱了。XFF就会按照代理链将一系列的ip地址存储起来。
  • 由图可得,在程序服务器中拿最原始的ip逻辑:
    • 如果XFF不为空,拿第一个
    • 为空,拿XRI
    • 如果XRI为空,拿remoteAddr,即只能拿最直接发给他的机器的ip
  • 代码

    public static String getIp(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for"); 
        if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(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();  
            if(ip.equals("127.0.0.1") || ip.equals("0:0:0:0:0:0:0:1")){  
                //根据网卡取本机配置的IP  
                InetAddress inet=null;  
                try {  
                    inet = InetAddress.getLocalHost();  
                } catch (UnknownHostException e) {  
                    e.printStackTrace();  
                }  
                ip= inet.getHostAddress();  
            }
        } 
        return ip;
    }
    
  • 参考文章
  • 参考文章
  • 代码示例:D:/dieaprojects/thz/thz-parent/thz-common/IPUtil