APIGateway中获取客户端IP的方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了APIGateway中获取客户端IP的方法相关的知识,希望对你有一定的参考价值。

参考技术A 在使用ServletRequest获取客户端ip的时候,不仅仅只使用getRemoteHost来获取,还要使用XFF(X-Forwarded-For)。

X-Forwarded-For是HTTP扩展头部,不是HTTP/1.1协议中的定义,但是现在基本是标准了,X-Forwarded-For存储了客户端IP和请求链路上各个代理IP。

加入一个请求从IP1位置开始,经过IP2,IP3,IP4三个代理然后到达服务端,那么使用ServletRequest的getRemoteHost获取到的IP是:IP4,X-Forwarded-For中存储的是:

我们可以使用X-Forwarded-For中的值来获取真是IP:

但是如果伪造请求链路,客户端请求的时候手动添加X-Forwarded-For的值,就可能不能获取到正确的IP。

源码: https://github.com/dachengxi/APIGateway
原文链接: https://cxis.me/2020/04/12/APIGateway%E4%B8%AD%E8%8E%B7%E5%8F%96%E5%AE%A2%E6%88%B7%E7%AB%AFIP%E7%9A%84%E6%96%B9%E6%B3%95/

Tomcat中获取客户端真实IP及协议

获取客户端真实IP
ServletRequest接口提供了getRemoteAddr方法用于获取客户端IP,但是当客户端通过代理服务器访问后端服务器的时候,服务器调用getRemoteAddr方法会返回最近的代理服务器的IP而非客户端真实IP。这种情况下通常是使用X-Forwarded-For请求头来获取客户端真实IP。
X-Forwarded-For简称XFF头,它保存了客户端和各级代理服务器的IP,只有在通过了HTTP正向代理服务器或者反向代理服务器时才会添加该项,一般格式如下:X-Forwarded-For: client1, proxy1, proxy2。基本流程是,当client1发出请求且请求没有经过任何的代理服务器,那么此时没有X-Forwarded-For;当请求经过proxy1的时候,proxy1将client1的IP添加到X-Forwarded-For中,此时X-Forwarded-For: client1;当请求经过proxy2的时候,proxy2将proxy1的IP添加到X-Forwarded-For中,此时X-Forwarded-For: client1, proxy1,以此类推。它在正向代理软件(如Squid)和反向代理软件(如Nginx)中都是标准用法。
X-Real-IP没有相关的标准,可以在代理中配置这个请求头的值为客户端真实IP,但是还是推荐使用X-Forwarded-For,因为Nginx一般配置X-Real-IP为$remote_addr,如果经过多级代理,就无法拿到客户端真实IP了。
以Nginx反向代理为例,Nginx里配置如下:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
proxy_set_header指令用于设置HTTP请求头,$remote_addr变量表示客户端IP,$proxy_add_x_forwarded_for变量表示客户端HTTP请求头中的X-Forwarded-For再加上“,”和$remote_addr。
在Tomcat中可以使用如下代码获取客户端真实IP:
String ip = request.getHeader("x-forwarded-for");
if (ip != null && ip.length() != 0) {
if (ip.indexOf(",") != -1) {
ip = ip.split(",")[0];
}
}
 
获取真实请求协议
一般情况下,反向代理服务器请求后端服务器时是采用http协议,而客户端访问反向代理服务器时是采用https协议,这种情况下,后端服务器302重定向到某个相对路径时会读取到请求的协议为http,导致Location响应头指中的URL的协议为http,重定向失败。
Tomcat的org.apache.catalina.valves.RemoteIpValve可以用来解决上述问题。
以Nginx反向代理为例,Nginx里配置如下:
proxy_set_header X-Forwarded-Proto $scheme
$scheme表示请求协议,值为http或https。
Tomcat配置如下:
<Host name="localhost" appBase=......>
<Valve className="org.apache.catalina.valves.RemoteIpValve" protocolHeader="X-Forwarded-Proto" />
<Context path="/" docBase=....../>
</Host>

 

以上是关于APIGateway中获取客户端IP的方法的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat中获取客户端真实IP及协议

java servlet获取客户端IP

JS和C#.NET获取客户端IP

获取客户端公共 IP 的最可靠方法

如何获取客户端ip

javaweb获取客户端真实ip