概要

一般在单机版的tomcat获取请求来源的ip,可以使用下面方式这么干,下文的request是HttpServletRequest对象。

    String remoteAddr = request.getRemoteAddr();

但是如果了使用反向代理例如niginx,由于对客户请求的代理,此时request.getRemoteAddr()获取要么是本级地址127.0.0.1 要么就是192.168.x.x这个内网地址,因为这种获取Ip的方式仅限与客户端和服务器端直接通信的方式才有效。在知乎上看到了一个很形象的反向代理图,如下所示:

反向代理对服务器做了代理,客户端是和代理进行通信。所以这种获取ip地址的信息获取到的是内网ip地址。
在nginx反向代理中,在nginx.conf 我们常常可以看到如下配置:X-Real-IP,X-Forwarded-For.

   location / {root   html;index  index.html index.htm index.jsp;#proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass http://192.168.1.224;}

由于客户端和服务器端中间有个代理层的存在,所以服务器无法直接拿到客户真实的ip地址,在代理转发客户请求的时候,请求头(即Header)增加了X-FORWARDED-FOR这个属性,这个属性是追踪原来客户端和服务器端的IP地址。只有通过了Http代理或者负载均衡服务器才会有这个属性。当客户端发起请求时,将会有以下5步操作。

  1. dns域名解析,通过域名找到ip
  2. 代理服务器的TCP监听端口,nginx默认80端口,当有TCP连接后,将客户端请求经过处理发送到服务器
  3. 服务器对接收到的Http数据包进行解压,解密,创建会话并处理请求
  4. 服务器处理和相应请求后,将相应转发给代理服务器
  5. 代理服务器将服务端的响应在转发给客户端服务器

所以整个请求中,客户端并没有和服务器端直接进行通信,所以request.getRemoteAddr()获取的是代理服务器的地址,因为服务器接收的是代理服务器发起的请求。
所以可以用下面方式获取客户端IP地址

获取Ip调用的方法

    /*** 获取IP地址**/public static String getIpAddr(HttpServletRequest request){String ip = request.getHeader("X-Real-IP");if(!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip))return ip;ip = request.getHeader("X-Forwarded-For");if(!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)){int index = ip.indexOf(',');if(index != -1)return ip.substring(0, index);elsereturn ip;}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.getHeader("HTTP_CLIENT_IP");if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))ip = request.getHeader("HTTP_X_FORWARDED_FOR");if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))ip = request.getRemoteAddr();return ip;}
  • 相关请求头解释
String ip = request.getHeader("X-Real-IP");

X-Real-IP是Nginx用来获取用户的真实ip地址,但是有时候可能获取不到返回是UNKONWN。所以当获取不到使用下面方式进行获取:

String ip = request.getHeader("X-Forwarded-For");

X-Forwarded-For 有时候可能获取不到,因为服务器不一定使用了反向代理,所以可能返回的也是UNKONWN,获取不到可以使用以下方式进行获取:

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

Proxy-Client-IP 是apache服务器定制一个请求头,这个属性只在apache服务器才可以看到。所以当服务器不是apache服务器,也会返回UNKONWN

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

WL- Proxy-Client-IP 其中WL是weblogic的缩写,这通常用户weblogic服务器环境中,也可能返回UNKONWN

String ip = request.getHeader("HTTP_CLIENT_IP");

HTTP_CLIENT_IP 有些代理服务器会加上此配置

String ip = request.getHeader("HTTP_X_FORWARD_FOR");

HTTP_X_FORWARD_FOR 可以在nginx配置此项,一般为 HTTP_X_FORWARD_FOR $remote_addr;
看了上面的相关头解释和获取IP的方法,则可以将其集成到我们的项目中,如下采用webService接口获取IP和基于Spring MVC方式获取IP

webService获取IP

下面以scala定一个webService接口

  @Path("/webService/getIp")@POSTdef getClientIp(@Context httpServletRequest: HttpServletRequest): String

实现类:

   // 获取客户端的ip
override def getClientIp(@Context httpServletRequest: HttpServletRequest): String = {var ip =""Try({ip = StringUtils.defaultIfBlank(getRemoteIP(httpServletRequest), "unknown")println("获取ip="+ip)}) match {case Success(_) => ipcase Failure(e) => {throw e}}}

SpringMVC获取IP

@PostMapping(Array("/springMvc/getIp"))def getIp(httpRequest: HttpServletRequest): String = {var ip =""Try({ip = StringUtils.defaultIfBlank(getRemoteIP(httpServletRequest), "unknown")println("获取ip="+ip)}) match {case Success(response) => ipcase Failure(e) => throw e}}

所以使用SpringMvc方式获取ip还是webService可以使用上面的案列,非常简单。

Java从代理服务器中获取客户端真实IP的方法相关推荐

  1. 获取客户端真实ip的方法

    为什么需要获取客户端真实ip ip地址是按地域分布的,服务器获取到客户端ip后可以做流量统计和分析,服务器也可以针对客户端ip做一些定制化的功能,比如限流和黑白名单. 网络环境十分复杂,客户端发出的一 ...

  2. PHP获取客户端真实IP的方法

    摘要: 利用getenv获取获取用户真实ip可以获取相当可观的用户数据,不管是做大数据还是数据备份查找来源,都是不错的选择. 好处: 一个网站,获取用户是非常有必要的,你获得了ip可以干嘛?简单了说, ...

  3. 获取客户端真实 IP

    Tomcat + Nginx 反向代理获取客户端真实IP.域名.协议.端口 Nginx 反向代理后,Servlet 应用通过 request.getRemoteAddr() 取到的 IP 是 Ngin ...

  4. python获取客户端ip_各种脚本语言获取客户端真实IP的方法

    各种语言获取客户端真是ip的方法 1.PHP脚本获取客户端真实ip的方法 整体思路:需要依次检查HTTP_CLIENT_IP.HTTP_X_FORWARDED_FOR.REMOTE_ADDR这三个是否 ...

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

    转载自 干货:Java正确获取客户端真实IP方法整理 在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的.但是在通过了Apach ...

  6. vue获取url中ip_Kubernetes 集群中这样获取客户端真实 IP

    Kubernetes 依靠 kube-proxy 组件实现 Service 的通信与负载均衡.在这个过程中,由于使用了 SNAT 对源地址进行了转换,导致 Pod 中的服务拿不到真实的客户端 IP 地 ...

  7. 获取客户端真实IP地址

    Java-Web获取客户端真实IP: 发生的场景:服务器端接收客户端请求的时候,一般需要进行签名验证,客户端IP限定等情况,在进行客户端IP限定的时候,需要首先获取该真实的IP. 一般分为两种情况: ...

  8. 获取客户端真实IP方法

    2019独角兽企业重金招聘Python工程师标准>>> 我们经常会记录审计日志,那么如何获取客户端真实IP呢?让我们了解一下HTTP协议头吧. 在讨论获取客户端IP 地址前,我们首先 ...

  9. golang 获取客户端真实IP地址

    [Go]获取用户真实的ip地址 用户请求到达提供服务的服务器中间有很多的环节,导致服务获取用户真实的 ip 非常困难,大多数的框架及工具库都会封装各种获取用户真实 ip 的方法,在 exnet 包中也 ...

最新文章

  1. 阿里园区生态技术联盟启动大会
  2. while loading shared libraries: libmysqlclient....
  3. POCO:InvalidOperationError:Mapping and metadata information could not be found for Entity Type
  4. 过年7天乐,学nodejs 也快乐
  5. 【数理知识】《数值分析》李庆扬老师-第3章-函数逼近与快速傅里叶变换
  6. 气死我的存储过程和用户定义函数
  7. Kibana安装及简单使用
  8. 以获客为目标 ,首席增长官从0到1实现用户增长
  9. (转)扩展KMP算法模板
  10. C++ 面向对象(二)多态 : 虚函数、多态原理、抽象类、虚函数表、继承与虚函数表
  11. Visual Studio Online,带来四种开发模式,未来已来。
  12. 物联网通信协议——比较-MQTT、 DDS、 AMQP、XMPP、 JMS、 REST、 CoAP
  13. 在 Mac 上的 Safari 浏览器中如何存储网页的一部分或整个网页?
  14. java txt转换excel_Java实现将txt文件转成xls文件的方法
  15. 2020 泰迪杯 C 题
  16. 最全面的PLC学习网站
  17. openCms安装技巧
  18. Tesla又撞,能上天的马斯克,自动驾驶为何只有如此水准
  19. linux秘钥登录使用authorized_keys不生效
  20. 计算机的文件打开记录怎么删,怎样删除最近使用的文档记录,电脑文档文件怎么删除...

热门文章

  1. 山东电子职业技术学院html,山东电子职业技术学院全景-360度,720度,高清全景地图-expoon网展...
  2. 淘宝店铺宝贝 下架时间到底还影响搜索排名么?
  3. MySQL 5.7 界面安装 - Windows(结尾附视频)
  4. Tensorflow + PyTorch 安装(CPU + GPU 版本)
  5. 音乐平台Sparkify流失用户预测
  6. arctime必须要java_更新MacOS catalina 后,arctime 无法使用,因为Java版本无法配适,怎么解决?...
  7. android 解析ksc字幕文件,KSC字模发布帖(注:KSC字幕可以用KAJConvert3转成KAJ)
  8. 春节档票房超30亿 互联网资本新旧势力赛跑
  9. 如何建立产品属性管理规范,提升元器件采购报价效率?
  10. 读《美国纽约摄影学院摄影教材》上册