Struts如何获取客户端ip地址
在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。
经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的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地址的方法一:
- 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地址的方法二:
- 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
以上方法还不行的话就采用如下方法:
/**
* 从客户端请求中获取客户端的IP
* @param request
* @return
*/
public static String getIpAddr(HttpServletRequest request){
String ipAddress = request.getHeader("x-forwarded-for");
if(isAble(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}else if(isAble(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}else if (isAble(ipAddress)) {
ipAddress = request.getHeader("HTTP_CLIENT_IP");
}else if (isAble(ipAddress)) {
ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR");
}else if (isAble(ipAddress)) {
ipAddress = request.getRemoteAddr();
}
//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if(ipAddress!=null && ipAddress.length()>15){ //"***.***.***.***".length() = 15
if(ipAddress.indexOf(",")!=-1){
ipAddress = ipAddress.substring(0,ipAddress.indexOf(","));
}else{
ipAddress = ipAddress.substring(0, 15);
}
}
return ipAddress;
}
/**
* 方法说明:判断ip地址是否可用<br/>
*
* @param ipAddress
* @return
*
*/
public static boolean isAble(String ipAddress){
return ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<以下摘自 http://www.cnblogs.com/zhengyun_ustc/archive/2012/09/19/getremoteaddr.html,感谢原作者>
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;
}
- 在默认情况下,Nginx 并不会对 XFF 头做任何处理
- 此时 Nginx 后面的 Resin/Apache/Tomcat 通过 request.getHeader("X-FORWARDED-FOR") 获得的ip仍然是原始ip。
- 当 Nginx 设置 X-Forwarded-For 等于 $proxy_add_x_forwarded_for 时:
- 如果从CDN过来的请求没有设置 XFF 头(通常这种事情不会发生),XFF 头为 CDN 的ip
- 此时相对于 Nginx 来说,客户端就是 CDN
- 如果 CDN 设置了 XFF 头,我们这里又设置了一次,且值为$proxy_add_x_forwarded_for 的话:
- XFF 头为“客户端IP,Nginx负载均衡服务器IP”,这样取第一个值即可
- 这也就是大家所常见的场景!
Client -> Apache WebServer + Weblogic http plugin -> Weblogic Instances
proxy_set_header HTTP_CLIENT_IP $remote_addr;
实际上,REMOTE_ADDR 是客户端跟服务器“握手”时的IP,但如果使用了“匿名代理”,REMOTE_ADDR 将显示代理服务器的ip,或者最后一个代理服务器的ip。请参考附录B。
内网IP:172.16.100.10
客户端IP:123.123.123.123
测试页面: test.jsp
<%
out.println("x-forwarded-for: " + request.getHeader("x-forwarded-for"));
out.println("remote hosts: " + request.getRemoteAddr());
%>
nginx 配置一proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;wget测试wget -O aa --header="X-Forwarded-For:192.168.0.1" "http://test.com/test.jsp"页面返回结果:x-forwarded-for: 192.168.0.1, 123.123.123.123remote hosts: 172.16.100.10curl测试curl -H "X-Forwarded-For:192.168.0.1" "http://test.com/test.jsp"x-forwarded-for: 192.168.0.1, 123.123.123.123remote hosts: 172.16.100.10
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
wget测试:
wget -O aa --header="X-Forwarded-For:192.168.0.1" "http://test.com/test.jsp"
页面返回结果:
x-forwarded-for: 123.123.123.123
remote hosts: 172.16.100.10
curl测试
curl -H "X-Forwarded-For:192.168.0.1" "http://test.com/test.jsp"
x-forwarded-for: 123.123.123.123
remote hosts: 172.16.100.10
测试结果:
1、配置
增加了一个真实ip X-Forwarded-For,并且顺序是增加到了“后面”。
2、配置
清空了客户端伪造传入的X-Forwarded-For,
保证了使用 request.getHeader("x-forwarded-for") 获取的ip为真实ip,
或者用“,”分隔,截取 X-Forwarded-For 最后的值。
Struts如何获取客户端ip地址的更多相关文章
- 在Thinkphp3.2.3框架下实现自动获取客户端IP地址的get_client_ip()函数
在Thinkphp框架下使用get_client_ip()函数获取客户端IP地址十分方便: 一行代码便可以实现:$ip = get_client_ip(); 但当我们测试时会遇到后台获取的IP地址显示 ...
- JAVA获取客户端IP地址
在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实I ...
- (转)【ASP.NET开发】获取客户端IP地址 via C#
[ASP.NET开发]获取客户端IP地址 via C# 说明:本文中的内容是我综合博客园上的博文和MSDN讨论区的资料,再通过自己的实际测试而得来,属于自己原创的内容说实话很少,写这一篇是为了记录自己 ...
- php获取客户端ip地址
本文介绍一个,php获取客户端的IP地址的实例代码,有需要的朋友参考下吧. 获取客户端IP地址的代码,如下: 复制代码代码示例: <?php//取得客户端IP的函数function get_cl ...
- 获取客户端IP地址 via C#
获取客户端IP地址 via C# 说明:本文中的内容是我综合博客园上的博文和MSDN讨论区的资料,再通过自己的实际测试而得来,属于自己原创的内容说实话很少,写这一篇是为了记录自己在项目中做过的事情,同 ...
- thinkphp 获取客户端ip地址方法
/** * 获取客户端IP地址 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 * @param boolean $adv 是否进行高级模式获取(有 ...
- 获取客户端IP地址定位城市信息
获取客户端IP地址定位城市信息 1.首先获取客户端的IP地址 function getIPaddress(){ $IPaddress=''; if (isset($_SERVER)){ if (iss ...
- Tp框架获取客户端IP地址
/** * 获取客户端IP地址 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 * @return mixed */ function get_cl ...
- thinkphp之获取客户端IP地址
/** * 获取客户端IP地址 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 * @return mixed */ function get_cl ...
随机推荐
- 1-2Html与CSS的关系
Html和CSS的关系 基于微信的后台开发须要掌握的基础知识包括有:HTML.CSS.JavaScript语言. 以下我们就来了解下这三门技术都是用来实现什么的: 1. HTML是网页内容的载体.内容 ...
- 【Flash 插件】时钟类插件
1.honehone_clock人体时钟实现 原理:就是在网页上播放已写好的.SWF文件. 效果如下: 效果一:背景透明,推荐为白色或浅背景 效果二:背景白色,推荐黑色或深色背景 实现步骤: 先引用 ...
- hbase-0.94安装方法具体解释
先决条件: 1)java环境,须要安装java1.6以上版本号 2)hadoop环境.因为HBase架构是基于其它文件存储系统的,因此在分布式模式下安装Hadoop是必须的,可是,假设 ...
- 在 Java SE 6 中监视和诊断性能问题
Java™ Platform, Standard Edition 6 (Java SE) 专注于提升性能,提供的增强工具可以管理和监视应用程序以及诊断常见的问题.本文将介绍 Java SE 平台中监视 ...
- Jacoco覆盖率工具使用
Jacoco介绍 Jacoco是一个开源的覆盖率工具.Jacoco可以嵌入到Ant .Maven中,并提供了EclEmma Eclipse插件,也可以使用JavaAgent技术监控Java程序.很多第 ...
- Laravel.log日志超级大!怎么办!
备份项目,发现下载好久没有下载下来.提了网速还是下载了45分钟 解压,解压了25分钟. 想着以为是附件太多... 进入了upload发现也就几百兆. 想看里面内容又打不开... Laravel 的日 ...
- IDC 知识库
http://www.51idc.com/help/supportHelp.html Host key verification failed解决IIS错误信息--另一个程序正在使用此文件,进程无法访 ...
- 关于html中的doctype的重要性的认知以及IE的浏览器模式与文档模式
浏览器模式”用于切换IE针对该网页的默认文档模式.对不同版本浏览器的条件备注解析.发送给网站服务器的用户代理(User-Agent)字符串的值.网站可以根据浏览器返回的不同用户代理字符串判断浏览器的版 ...
- webservice系统学习笔记10-使用jax-ws创建基于tomcat类型的容器的ws服务
1.在web-info目录下新建目录wsdl 2.在1步的目录下 新建文件user.wsdl <?xml version="1.0" encoding="UTF-8 ...
- Json动态添加属性
一维Json: var Json={}: Json.name="小明"; Json.age="12": Json.sex="男": 输出效果 ...
