作者:蔡永吉  来源:http://bit.ly/33H8RMm想必大家对这段代码并不陌生:

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;}

是的,你搜索到的“java获取真实IP地址”大多都是如此。但是,以上代码真

的对吗?

那么我们看一下具体的代码。如上,判断ip地址的优先级是

"x-forwarded-for">"Proxy-Client-IP">"WL-Proxy-Client-IP">request.getRemoteAddr()
其中带引号的都是从header中获取的。

等等!我们都知道header中的值是可以更改的。比如:

$.ajax({    type : "GET",    headers : {"X-Forwarded-For":randomIp,"WL-Proxy-Client-IP":randomIp},    contentType : 'application/x-www-form-urlencoded;charset=utf-8',    url : url,    data:params,    dataType : "text",    success : function(data) {        count++;        console.log("时间:【"+new Date()+"】 执行成功:【"+count+"】次:"+data);    if(max>0){        setTimeout(function wait(){            console.log("等待"+(timeWait)+"ms ...");            vote(max,getRandomNum(maxWait,minWait));        },timeWait);    }    }}

代码出自:https://github.com/caiyongji/vote-2.0/blob/master/Vote-2.0.js其中headers属性X-Forwarded-For,WL-Proxy-Client-IP不就是被更改了吗?那么,为什么会有这个版本的“java获取真实IP地址”的方法呢?并且搜索引擎所能检索到的结果大多都是这一个?打个比方说,如果这个解决办法是一本秘籍的话,那么,我们找到的只是“java获取真实IP地址”残卷。而剩下的部分在这里:

#Nginx 设置location  ~  ^/static {proxy_pass  ....;proxy_set_header X-Forward-For $remote_addr ;}

这段配置是在前端Nginx反向代理上的(其他反向代理请自行搜索),这段配置

作的事情是将X-Forward-For替换为remote_addr,再将X-Forward-For在内网各服务器间安全传输。

这里我再针对TCP/IP多做一些解释,众所周知TCP/IP建立连接时需要三次握手的,并且,只有知道了client端请求的IP地址,server端的数据才能返回给client,所以client想要获取到数据就必须提供真实的IP(DDOS攻击除外),而request.getRemoteAddr()获取的就是用户最真实的IP。
那么为什么不直接使用使用request.getRemoteAddr()这个方法呢?如果没有反向代理的话当然可行。但是出于安全原因,现在大多数的服务都使用代理服务器(如Nginx,代理服务器可以理解为用户和服务器之间的中介,双方都可信任。),而用户对代理服务器发起的HTTP请求,代理服务器对服务集群中的真实部署的对应服务进行“二次请求”,所以最终获取的IP是代理服务器在内网中的ip地址,如192.168.xx.xx/10.xx.xx.xx等等。所以在使用了反向代理的情况下,request.getRemoteAddr()获取的是反响代理在内网中的ip地址。所以在反向代理中将X-Forward-For替换为remote_addr,即,真实的IP地址。之后在内网中获取的x-forwarded-for便是真实的ip地址了。最后给出完整解决方案(Nginx为例):JAVA部分:

public class IpUtils {    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 longToIpV4(long longIp) {        int octet3 = (int) ((longIp >> 24) % 256);        int octet2 = (int) ((longIp >> 16) % 256);        int octet1 = (int) ((longIp >> 8) % 256);        int octet0 = (int) ((longIp) % 256);        return octet3 + "." + octet2 + "." + octet1 + "." + octet0;    }    public static long ipV4ToLong(String ip) {        String[] octets = ip.split("\\.");        return (Long.parseLong(octets[0]) << 24) + (Integer.parseInt(octets[1]) << 16)                + (Integer.parseInt(octets[2]) << 8) + Integer.parseInt(octets[3]);    }    public static boolean isIPv4Private(String ip) {        long longIp = ipV4ToLong(ip);        return (longIp >= ipV4ToLong("10.0.0.0") && longIp <= ipV4ToLong("10.255.255.255"))                || (longIp >= ipV4ToLong("172.16.0.0") && longIp <= ipV4ToLong("172.31.255.255"))                || longIp >= ipV4ToLong("192.168.0.0") && longIp <= ipV4ToLong("192.168.255.255");    }    public static boolean isIPv4Valid(String ip) {        return pattern.matcher(ip).matches();    }    public static String getIpFromRequest(HttpServletRequest request) {        String ip;        boolean found = false;        if ((ip = request.getHeader("x-forwarded-for")) != null) {            StrTokenizer tokenizer = new StrTokenizer(ip, ",");            while (tokenizer.hasNext()) {                ip = tokenizer.nextToken().trim();                if (isIPv4Valid(ip) && !isIPv4Private(ip)) {                    found = true;                    break;                }            }        }        if (!found) {            ip = request.getRemoteAddr();        }        return ip;    }}

Nginx部分:

location  ~  ^/static {proxy_pass  ....;proxy_set_header X-Forward-For $remote_addr ;}
这就是差距啊~~~

热文推荐

作为新手,我终于明白了在IDEA中如何配置和部署Web项目?

老大,你为什么在代码中要求我们使用LocalDateTime而不是Date?

醉了,竟然这么多人连Ftp、Ftps与Sftp的差异都不知道...

同时,分享一份Java面试资料给大家,覆盖了算法题目、常见面试题、JVM、锁、高并发、反射、Spring原理、微服务、Zookeeper、数据库、数据结构等等。获取方式:点“在看”,关注公众号并回复 面试 领取。

502 proxy error解决方法_老大说,网上这种获取真实IP地址的方法不对,我不信......相关推荐

  1. 老大说,网上这种获取真实IP地址的方法不对,我不信...

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:蔡永吉  来源:http://bit.ly/33H8RMm ...

  2. 查找“CDN、负载均衡、反向代理”等大型网络真实IP地址的方法

    查找"CDN.负载均衡.反向代理"等大型网络真实IP地址的方法     首先,CDN.负载均衡.反向代理还分为很多层,有时查出来的是最外层的 CDN 服务器群,真实的机器是不对外开 ...

  3. android 获取wifi的ip地址吗,Android开发实现在Wifi下获取本地IP地址的方法

    本文实例讲述了Android开发实现在Wifi下获取本地IP地址的方法.分享给大家供大家参考,具体如下: 代码核心介绍: WifiManager类提供了对设备Wifi功能的管理,包括Wifi开关的打开 ...

  4. html获取访客ip,jQuery获取访问者IP地址的方法(基于新浪API与QQ查询接口)

    本文实例讲述了jQuery获取访问者IP地址的方法.分享给大家供大家参考,具体如下: $(document).ready(function(){ //通过调用新浪IP地址库接口查询用户当前所在国家.省 ...

  5. PHP获取客户端真实IP地址的方法

    php获取客户端IP地址有四种方法,这五种方法分别为 1 2 3 4 REMOTE_ADDR HTTP_CLIENT_IP HTTP_X_FORWARDED_FOR HTTP_VIA REMOTE_A ...

  6. 获取用户Ip地址通用方法常见安全隐患 x-forwarded-for

    分析过程 这个来自一些项目中,获取用户Ip,进行用户操作行为的记录,是常见并且经常使用的. 一般朋友,都会看到如下通用获取IP地址方法. function getIP() { if (isset($_ ...

  7. 如何用ASP获取真实IP地址_草根编程

    大家都知道,在ASP中可以使用Request.ServerVariables("REMOTE_ADDR")来取得客户端的IP地址,但如果客户端是使用代理服务器来访问,那取到的就是代 ...

  8. php $_server[remote_addr];,PHP获取客户端IP地址的方法$_SERVER['REMOTE_ADDR']

    /** * 获取客户端IP地址 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 * @param boolean $adv 是否进行高级模式获取(有 ...

  9. java获取真实ip的方法

    在网络中,如果不想被人监听,那么就需要获取 IP地址了,在电脑中我们可以使用到 ip地址获取工具,那么如何在 Java中获取真实的 IP地址呢? 1.首先我们需要先准备一台电脑,然后将电脑进行联网: ...

最新文章

  1. c++ string 头文件_“延期不延学” 第25期 | C++篇 | C/C++常用函数
  2. C# 效率也不是很差嘛
  3. java短信接口 调用_带你了解短信接口的调用
  4. 就业形势如此的严峻,你为何不努力?
  5. Opencv实战【3】——图像修复与图像锐化(darling in the franxx)
  6. Makefile中 变量赋值含义
  7. 【Codeforces 631C 】Report(单调栈,思维模拟)
  8. 程序包android.support.annotation不存在_efcore技巧贴也许有你不知道的使用技巧
  9. 线路速度之实战***
  10. 并发编程 进程基础
  11. 使用电脑开发的,连个黑屏休眠都不会设置?
  12. 史蒂夫 乔布斯:遗失的访谈
  13. CSS 中的层叠,层级关系
  14. 阿里2018笔试题 之 三种颜色排列
  15. 几种滤波器matlab,Matlab滤波器种类及参数设置
  16. 2022大宗商品现货交易所织梦网站模板源码+大气美观
  17. win10解决安装.NET Framework 3.5安装不上,错误代码:0x800F081F,解决办法:超级管用。
  18. python 第一行包含一个整数n、表示行数_输入 第一行输入一个整数n(1 = n = 100)表示测试样例个数 接下来n行,一...
  19. 二、【玩转 华为Atlas200 DK】之连接电脑和Atlas 200
  20. HTK 安装、编译以及测试——Ubuntu 14.04

热门文章

  1. 腾讯 2016 春季实习校招二面回忆(C++后台)
  2. MyBatis映射文件3(参数处理Map)
  3. C# WPF 多个window 相互覆盖的次序控制 不用topmost
  4. Istio最佳实践:在K8s上通过Istio服务网格进行灰度发布
  5. [Bzoj4817] [Sdoi2017]树点涂色 (LCT神题)
  6. 手机尺寸相关的概念 +尺寸单位+关于颜色
  7. C#:使用ListView动态添加数据一直闪烁的解决办法
  8. Timus 1741
  9. 改进我个人知识管理手段
  10. 扎克伯格靠AI挺过危机,Facebook满血复活还需3年