Java正确获取客户端真实IP方法整理

转载自 干货:Java正确获取客户端真实IP方法整理

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

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

经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息。用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。

当我们访问http://www.abc.com/index.jsp/时,其实并不是我们浏览器真正访问到了服务器上的index.jsp文件,而是先由代理服务器去访问http://192.168.1.110:2046/index.jsp,代理服务器再将访问到的结果返回给我们的浏览器,因为是代理服务器去访问index.jsp的,所以index.jsp中通过request.getRemoteAddr()的方法获取的IP实际上是代理服务器的地址,并不是客户端的IP地址。

外界流传的JAVA/PHP服务器端获取客户端IP都是这么取的:

伪代码:

1)ip = request.getHeader("X-FORWARDED-FOR ")

2)如果该值为空或数组长度为0或等于"unknown",那么:

 ip = request.getHeader("Proxy-Client-IP")

3)如果该值为空或数组长度为0或等于"unknown",那么:

 ip = request.getHeader("WL-Proxy-Client-IP")

4)如果该值为空或数组长度为0或等于"unknown",那么: 

ip = request.getHeader("HTTPCLIENTIP")

5)如果该值为空或数组长度为0或等于"unknown",那么:

 ip = request.getHeader("X-Real-IP")

6)如果该值为空或数组长度为0或等于"unknown",那么:

 ip = request.getRemoteAddr ()

先说说这些请求头的意思

  • X-Forwarded-For

这是一个 Squid 开发的字段,只有在通过了HTTP代理或者负载均衡服务器时才会添加该项。

格式为X-Forwarded-For:client1,proxy1,proxy2,一般情况下,第一个ip为客户端真实ip,后面的为经过的代理服务器ip。现在大部分的代理都会加上这个请求头。

  • Proxy-Client-IP/WL- Proxy-Client-IP

这个一般是经过apache http服务器的请求才会有,用apache http做代理时一般会加上Proxy-Client-IP请求头,而WL-Proxy-Client-IP是他的weblogic插件加上的头。

  • HTTPCLIENTIP

有些代理服务器会加上此请求头。

  • X-Real-IP nginx代理一般会加上此请求头。

下面是一个参考获取客户端IP地址的方法:

public static String getIpAddress(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();}if (ip.contains(",")) {return ip.split(",")[0];} else {return ip;}
}

如果使用的是Druid连接池,可以参考使用:com.alibaba.druid.util.DruidWebUtils#getRemoteAddr方法,但这个是经过多级代理的IP地址,需要自己处理下获取第一个。

有几点要注意

  1. 这些请求头都不是http协议里的标准请求头,也就是说这个是各个代理服务器自己规定的表示客户端地址的请求头。如果哪天有一个代理服务器软件用oooo-client-ip这个请求头代表客户端请求,那上面的代码就不行了。

  2. 这些请求头不是代理服务器一定会带上的,网络上的很多匿名代理就没有这些请求头,所以获取到的客户端ip不一定是真实的客户端ip。代理服务器一般都可以自定义请求头设置。

  3. 即使请求经过的代理都会按自己的规范附上代理请求头,上面的代码也不能确保获得的一定是客户端ip。不同的网络架构,判断请求头的顺序是不一样的。

  4. 最重要的一点,请求头都是可以伪造的。如果一些对客户端校验较严格的应用(比如投票)要获取客户端ip,应该直接使用ip=request.getRemoteAddr(),虽然获取到的可能是代理的ip而不是客户端的ip,但这个获取到的ip基本上是不可能伪造的,也就杜绝了刷票的可能。(有分析说arp欺骗+syn有可能伪造此ip,如果真的可以,这是所有基于TCP协议都存在的漏洞),这个ip是tcp连接里的ip。

参考 http://blog.csdn.net/sgx425021234/article/details/19043459 

http://blog.csdn.net/fengwind1/article/details/51992528



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/330862.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习性能评估指标(综合性总结)

转自:http://charleshm.github.io/2016/03/Model-Performance/ 分类 混淆矩阵1 True Positive(真正, TP):将正类预测为正类数.True Negative(真负 , TN):将负类预测为负类数.False Positive(假正, FP):将负类预测为正类数 → 误报…

单列集合List的实现类

List接口 [Collection】的子类 1.ArrayList【查询快&#xff0c;增删慢】 &#xff08;1&#xff09;ArrayList常见方法【部分】 //list[Collection的子类,也是接口],ArrayList也是其实现类 public class Demo2 {public static void main(String[] args) {List<String>…

8张图带你轻松温习Java知识

转载自 8张图带你轻松温习Java知识 1 字符串不变性 下面这张图展示了这段代码做了什么 [code ]String s "abcd"; s s.concat("ef");[/code] 2 equals()方法、hashCode()方法的区别 HashCode被设计用来提高性能。equals()方法与hashCode()方法的区别在…

Linux的安装及管理程序

一、如何在linux安装卸载软件 1. 编译安装 灵活性较高 难度较大 可以安装较新的版本 2. rpm安装&#xff08;redhat&#xff09; linux 包安装 查软件信息&#xff1a;是否安装&#xff0c;文件列表 rpm 软件名 3. yum yum是RPM升级版本&#xff0c;解决rpm的弊端 安装软件 首…

机器学习评价指标大汇总

转自&#xff1a; http://www.zhaokv.com/2016/03/ml-metric.html 在使用机器学习算法的过程中&#xff0c;针对不同场景需要不同的评价指标&#xff0c;在这里对常用的指标进行一个简单的汇总。 &#xff08;分类和拟合的评价指标&#xff0c;正好应用到本人的论文中&#xff…

阿里Druid连接池监控的两个坑

转载自 注意&#xff1a;阿里Druid连接池监控的两个坑阿里的Druid大家都知道是最好的连接池&#xff0c;其强大的监控功能是我们追求的重要特性。但在实际情况中也有不少坑&#xff0c;说下最近遇到的一个坑吧&#xff01; 问题1&#xff1a;不断打印error级别的错误日志sessio…

List集合相关应用

1.定义一个Collection类型的集合&#xff0c;存储以下字符串&#xff1a; “JavaEE企业级开发指南”, “Oracle高级编程”, “MySQL从入门到精通”, “Java基础教程” 完成以下功能 1.删除书名字符小于10个的元素&#xff0c;并打印 2.打印书名中包含“Java”的元素 public cl…

消息中间件ActiveMQ、RabbitMQ、RocketMQ、ZeroMQ、Kafka如何选型

转载自 消息中间件ActiveMQ、RabbitMQ、RocketMQ、ZeroMQ、Kafka如何选型&#xff1f; 最近要为公司的消息队列中间件进行选型&#xff0c;市面上相关的开源技术又非常多&#xff0c;如ActiveMQ、RabbitMQ、ZeroMQ、Kafka&#xff0c;还有阿里巴巴的RocketMQ等。 这么多技术&am…

机器学习(周志华)- 第2章模型评估与选择笔记

转自&#xff1a; https://samanthachen.github.io/2016/08/03/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0_%E5%91%A8%E5%BF%97%E5%8D%8E_%E7%AC%94%E8%AE%B02/ 经验误差与过拟合 错误率&#xff1a; 分类错误样本数占样本总数 精度&#xff1a; 1 - 错误率 误差&#xff1a;学习器…

单列集合Set的实现类TreeSet

Set接口 [Collection】的子类 TreeSet a.特点【无序&#xff0c;不可重复&#xff0c;查询快&#xff0c;可自动排序】&#xff0c;但需要指定排序规则&#xff0c;API中有一些类已经实现了Comparable接口],给出了默认排序规则&#xff0c;如:Integer:数值大小[升序] String:…

关于Java你不知道的10件事

转载自 关于Java你不知道的10件事 作为 Java 书呆子&#xff0c;比起实用技能&#xff0c;我们会对介绍 Java 和 JVM 的概念细节更感兴趣。因此我想推荐 Lukas Eder 在 jooq.org 发表的原创作品给大家。 你是从很早开始就一直使用 Java 吗&#xff1f;那你还记得它的过去吗&…

模型评估与选择 ( Bias(偏差),Error(误差),和Variance(方差) )

转自&#xff1a; https://github.com/familyld/Machine_Learning/blob/master/02model_evaluation_and_model_selection.md 机器学习中的Bias(偏差)&#xff0c;Error(误差)&#xff0c;和Variance(方差)有什么区别和联系&#xff1f; 参见 https://www.zhihu.com/question…

单列集合Set的实现类HashSet

Set接口 [Collection】的子类 HashSet 特点【无序&#xff0c;不可重复,不能排序】 默认比较地址值【地址相同的值相同】&#xff0c;重写后可比较内容【内容相同的值相同】 1.比较地址值【默认】 public class Demo1 {public static void main(String[] args) {HashSet<…

双列集合Map的实现类

Map接口【和Collection接口并列】 Map接口 成员方法【实现于Map接口&#xff0c;TreeMap也可实现&#xff0c;这里以HashMap为例】 //HashMap实现类 :无序[HashSet底存原理] 哈希表 public class Demo1 {public static void main(String[] args) {HashMap<String, Intege…

机器学习指标大汇总

转自&#xff1a; http://www.36dsj.com/archives/42271 作者&#xff1a;无影随想 在使用机器学习算法的过程中&#xff0c;针对不同场景需要不同的评价指标&#xff0c;在这里对常用的指标进行一个简单的汇总。 一、分类 1. 精确率与召回率 精确率与召回率多用于二分类问题。…

到底什么是分布式系统

转载自 到底什么是分布式系统分布式系统背景 说分布式系统必须要说集中式系统&#xff0c;集中式系统中整个项目就是一个独立的应用&#xff0c;整个应用也就是整个项目&#xff0c;所有的东西都在一个应用里面。 如下图所示如一个网站就是一个应用&#xff0c;最后是多个增加多…

Map集合相关应用

1.键盘录入一个字符串&#xff0c;求该字符串中每一个字符出现的次数。 要求&#xff1a;按照字母顺序打印 如: 录入的字符串为"apple"&#xff0c;打印 a(1) e(1) l(1) p(2) public class Demo4 {public static void main(String[] args) {//键盘录入Scanner sc n…

机器学习算法常用指标总结

转自&#xff1a; http://www.cnblogs.com/maybe2030/p/5375175.html#_label2 阅读目录 1. TPR、FPR&TNR 2. 精确率Precision、召回率Recall和F1值 3. 综合评价指标F-measure 4. ROC曲线和AUC 5. 参考内容 考虑一个二分问题&#xff0c;即将实例分成正类&#xff08;positi…

SLA服务可用性4个9是什么意思?怎么达到?

转载自 SLA服务可用性4个9是什么意思&#xff1f;怎么达到&#xff1f;SLA&#xff1a;服务等级协议&#xff08;简称&#xff1a;SLA&#xff0c;全称&#xff1a;service level agreement&#xff09;。是在一定开销下为保障服务的性能和可用性&#xff0c;服务提供商与用户间…

ROC和AUC介绍以及如何计算AUC

转自&#xff1a; http://alexkong.net/2013/06/introduction-to-auc-and-roc/ ROC&#xff08;Receiver Operating Characteristic&#xff09;曲线和AUC常被用来评价一个二值分类器&#xff08;binary classifier&#xff09;的优劣&#xff0c;对两者的简单介绍见这里。这篇…