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

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

如下图,原来是client端直接请求服务端,走A路线请求,这时候通过request.getRemoteAddr()方法可以准备的获取客户端的IP。但是做了代理之后呢,client端不是直接请求服务端,而是走B线路请求代理服务器,由代理器去请求服务端,这时候服务端通过request.getRemoteAddr()方法拿到的理所当然是代理服务器的地址了。

经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的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的Java类:

/**
* 常用获取客户端信息的工具
*
*/
public final class NetworkUtil {
/**
* Logger for this class
*/
private static Logger logger = Logger.getLogger(RandomCodeUtils.class); /**
* 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址;
*
* @param request
* @return
* @throws IOException
*/
public final static String getIpAddress(HttpServletRequest request) throws IOException {
// 获取请求主机IP地址,如果通过代理进来,则透过防火墙获取真实IP地址 String ip = request.getHeader("X-Forwarded-For");
if (logger.isInfoEnabled()) {
logger.info("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");
if (logger.isInfoEnabled()) {
logger.info("getIpAddress(HttpServletRequest) - Proxy-Client-IP - String ip=" + ip);
}
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
if (logger.isInfoEnabled()) {
logger.info("getIpAddress(HttpServletRequest) - WL-Proxy-Client-IP - String ip=" + ip);
}
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
if (logger.isInfoEnabled()) {
logger.info("getIpAddress(HttpServletRequest) - HTTP_CLIENT_IP - String ip=" + ip);
}
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
if (logger.isInfoEnabled()) {
logger.info("getIpAddress(HttpServletRequest) - HTTP_X_FORWARDED_FOR - String ip=" + ip);
}
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
if (logger.isInfoEnabled()) {
logger.info("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 = (String) ips[index];
if (!("unknown".equalsIgnoreCase(strIp))) {
ip = strIp;
break;
}
}
}
return ip;
}
}

Request获取用户真实IP(用作白名单过滤)的更多相关文章

  1. java 获取用户真实ip

    /** * 获取用户真实ip * @param request * @return */ public static String getIpAddr(HttpServletRequest reque ...

  2. Java中使用HttpRequest获取用户真实IP地址端口

    import javax.servlet.http.HttpServletRequest; /** * 自定义访问对象工具类 * * 获取对象的IP地址等信息 * @author X-rapido * ...

  3. 在有nginx做反向代理时候,如何获取用户真实Ip信息

    在获取用户的Ip地址时,不一定可以获取到用户真实的地址信息,这要看代理服务器的类型,代理服务器有普通匿名代理服务器,高匿代理服务器,像这种情况很难获取到用户真实的Ip地址 假如用户没有使用匿名代理服务 ...

  4. 获取用户真实IP:(模拟:客户端--F5--nginx--tomcat 后端获取用户真实IP)

    模拟:客户端--F5--nginx--tomcat 后端获取用户真实IP 192.168.109.137 :nginx01(充当第一层代理==F5)192.168.109.138 :nginx02(二 ...

  5. 如何根据HttpServletRequets获取用户真实IP地址

    最近的一个项目的某个功能获取用户的ip地址,添加用户的系统使用记录. 我发现当我直接使用getRemoteAddr()方法从HttpServletRequet中获取用户的ip时,获取到的是服务器的ip ...

  6. nginx反向代理获取用户真实ip

    nginx做反向代理时,默认的配置后端获取到的ip都是来自于nginx,如何转发用户的真实ip到后端程序呢?如是是java后端,用request.getRemoteAddr();获取到的是nginx的 ...

  7. PHP获取用户真实 IP , 淘宝IP接口获得ip地理位置(转)

    <?php /** * 获取用户真实 IP */ function getIP() { static $realip; if (isset($_SERVER)){ if (isset($_SER ...

  8. 多层代理获取用户真实IP

    1. 几个概念remote_addr:如果中间没有代理,这个就是客户端的真实IP,如果有代理,这就是上层代理的IP.X-Forwarded-For:一个HTTP扩展头,格式为 X-Forwarded- ...

  9. 根据HttpServletRequest获取用户真实IP地址

    原因: 当我们通过request获取客户端IP时,自身服务器通常会为了保护信息或者负载均衡的目的,对自身服务器做反向代理.此时如果我们通过request.getRemoteAddr();可能获取到的是 ...

随机推荐

  1. 豆瓣源安装requirements.txt

    豆瓣源安装requirements.txt pip install -i https://pypi.doubanio.com/simple/ -r requirements.txt

  2. C#学习笔记(28)——委托排序(2)自定义排序

    说明(2017-11-21 15:24:50): 1. 定义一个排序方法,参数是字符串数组,和委托.MySort(nums, string.Compare),调用时只需要更换里面的委托方法就行,或者直 ...

  3. 基于jQuery个性圆圈倒计时特效

    基于jQuery个性圆圈倒计时特效里面包含十几款不用效果的jQuery倒计时特效下载.效果图如下: 在线预览   源码下载 实现的代码. html代码: <section class=" ...

  4. andriod自定义视图

    一.通过View实现自定义视图 通过构造函数创建可视界面 public class MyView extends View { // Constructor required for in-code ...

  5. bootstrap table 自己设置值

    在使用bootstrap table的值默认是从 total rows 里面取,可是后台返回的json数据并不是这样的怎么办 可以使用 responseHandler  自定义: $(function ...

  6. 【Unity Shader】七、透明的Transparent Shader

    学习资料: http://www.sikiedu.com/course/37/task/459/show# 本例的代码基于上一篇文章,添加透明效果.为了便于区分新增的部分,该部分使用和红色加粗字体. ...

  7. NLP-训练个model出来写诗

    2018年新年,腾讯整出来个ai春联很吸引眼球,刚好有个需求让我看下能不能训出来个model来写出诗经一样的文风,求助了下小伙伴,直接丢过来2个github,原话是: 查了一下诗经一共38000个字, ...

  8. 临时文件夹迁移 temp位置移动

    方法/步骤 首先,在其他驱动器新建一个文件夹,给临时文件夹安个新家 桌面,右键"我的电脑",选择"属性" 点击"高级系统设置" 点击&quo ...

  9. Java编程的逻辑 (40) - 剖析HashMap

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

  10. 创建function实现hive表结果导出到mysql

    1. 创建临时function (这里两个包都是hive自带的,不需要自己开发的,可以根据名称查找对应的版本) add jar /opt/local/hive/lib/hive-contrib-.ja ...