根据Request获取客户端IP
转自:
http://www.cnblogs.com/icerainsoft/p/3584532.html
http://www.cnblogs.com/bingya/articles/3134227.html
在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr() ,这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。
如
果使用了反向代理软件,将http://192.168.1.110:2046/ 的URL反向代理为http://www.xxx.com/
的URL时,用request.getRemoteAddr() 方法获取的IP地址是:127.0.0.1 或 192.168.1.110
,而并不是客户端的真实IP。
经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接
通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息。用以跟踪原有的客户端IP地址和原来客
户端请求的服务器地址。当我们访问http://www.xxx.com/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.xxx.com/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 getRemoteHost(javax.servlet.http.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.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;
}
如果是Netty4.x
public String getRemoteIP(FullHttpRequest httpRequest) {
String ip = "";
try{
String ipForwarded = httpRequest.headers().get("x-forwarded-for");
if (StringUtils.isBlank(ipForwarded) || "unknown".equalsIgnoreCase(ipForwarded)) {
InetSocketAddress insocket = (InetSocketAddress)channel.remoteAddress();
ip = insocket.getAddress().getHostAddress();
} else {
ip = ipForwarded;
}
}catch(Exception e){
logger.error("getRemoteIP(): get remote ip fail!", e);
}
if("0:0:0:0:0:0:0:1".equals(ip)){
ip = "127.0.0.1";
}
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
package com.ctrip.cep.mockserver.util; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest;
import java.io.IOException; /**
* Created by lzyan on 2017/7/11.
*/
public final class NetworkUtil {
private static Logger logger = LoggerFactory.getLogger(NetworkUtil.class); /**
* 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址
*
* @param request
* @return
* @throws IOException
*/
public final static String getIpAddress(HttpServletRequest request) {
// 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址 String ip = request.getHeader("X-Forwarded-For");
// logger.debug("getIpAddress(HttpServletRequest) - X-Forwarded-For - String ip=" + ip); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
// logger.debug("getIpAddress(HttpServletRequest) - Proxy-Client-IP - String ip=" + ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
// logger.debug("getIpAddress(HttpServletRequest) - WL-Proxy-Client-IP - String ip=" + ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
// logger.debug("getIpAddress(HttpServletRequest) - HTTP_CLIENT_IP - String ip=" + ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
// logger.debug("getIpAddress(HttpServletRequest) - HTTP_X_FORWARDED_FOR - String ip=" + ip);
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
// logger.debug("getIpAddress(HttpServletRequest) - getRemoteAddr - String ip=" + ip);
}
} else if (ip.length() > 15) {
String[] ips = ip.split(",");
for (int index = 0; index < ips.length; index++) {
String strIp = ips[index];
if (!("unknown".equalsIgnoreCase(strIp))) {
ip = strIp;
break;
}
}
}
return ip;
} }
根据Request获取客户端IP的更多相关文章
- 根据Request获取客户端IP 内网IP及外网IP
在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr() ,这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实 ...
- Request获取客户端IP
获取客户端的IP地址的方法是:request.getRemoteAddr() ,这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了. ...
- C#服务器获取客户端IP地址以及归属地探秘
背景:博主本是一位Windows桌面应用程序开发工程师,对网络通信一知半解.一日老婆逛完某宝,问:"为什么他们知道我的地址呢,他们是怎么获取我的地址的呢?" 顺着这个问题我们的探秘 ...
- JAVA获取客户端IP地址
在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实I ...
- WebService及WCF获取客户端IP,端口
wcf获取客户端IP,端口 var context = OperationContext.Current; var properties = context.IncomingMessageProper ...
- asp.net获取客户端IP方法(转载)
最近web获取客户端ip,看到下面这篇文章,转载过来,一起分享(转载地址:http://www.cnblogs.com/yejun/archive/2008/02/26/1082485.html) 通 ...
- (转)【ASP.NET开发】获取客户端IP地址 via C#
[ASP.NET开发]获取客户端IP地址 via C# 说明:本文中的内容是我综合博客园上的博文和MSDN讨论区的资料,再通过自己的实际测试而得来,属于自己原创的内容说实话很少,写这一篇是为了记录自己 ...
- 获取客户端IP地址 via C#
获取客户端IP地址 via C# 说明:本文中的内容是我综合博客园上的博文和MSDN讨论区的资料,再通过自己的实际测试而得来,属于自己原创的内容说实话很少,写这一篇是为了记录自己在项目中做过的事情,同 ...
- ASP.NET获取客户端信息,获取客户端IP等等
山上明月 ASP.NET能知道的东西 获取服务器电脑名: Page.Server.ManchineName 获取用户信息: Page.User 获取客户端电脑名:Page.Request.UserHo ...
随机推荐
- servlet中web.xml配置详解
Web.xml常用元素 <web-app> 所有部署描述符文件的顶层(根)元素 <display-name></display-name>定义了WEB应用的名字 & ...
- [转]JSTL 自定义方法报错Invalid syntax for function signature in TLD.
Apache Tomcat/6.0.18 ${my:splitApply(apply)} <function> <name>splitApply</name> &l ...
- 完美解决"Encountered an NTFS Volume with a logfile ..."
完美解决Ghost镜像文件时出现"Encountered an NTFS Volume with a logfile that has not been flushed(536)" ...
- hello alibaba
http://ifeve.com/dubbo-learn-book/ http://ifeve.com/leader-follower-thread-model/ http://ifeve.com/a ...
- Linux软件源
Kali科大软件源: vim /etc/apt/sources.list 下面的粘帖进去. deb http://mirrors.ustc.edu.cn/kali kali main non-free ...
- Android图片处理(Matrix,ColorMatrix)
转发说明:原文链接http://www.cnblogs.com/leon19870907/articles/1978065.html 在编程中有时候需要对图片做特殊的处理,比如将图片做出黑白的,或者老 ...
- 两台centos之间传送文件
https://www.cnblogs.com/pangguoming/p/9282762.html
- js给原型增加新属性和方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Linux设备驱动剖析之Input(二)
分别是总线类型.厂商号.产品号和版本号. 1156行,evbit,设备支持的事件类型的位图,每一位代表一种事件,比如EV_KEY.EV_REL事件等等.BITS_TO_LONGS(nr)是一个宏,假设 ...
- elastaicsearch基础----->elastaicsearch的使用(一)
这里面我们总结一下es的一些基础使用. es的基础用法 一.es索引的创建 在postman中,请求url地址:192.168.1.112:9200/user.请求方式:PUT.请求内容如下: { & ...