SpringBoot项目获取客户端IP

本文主要介绍了SpringBoot项目中如何获取真实客户端IP,在应用前侧有nginx或cdn时应该如何处理。

X-Forwarded-For(简称XFF)是一个常见的(非正式使用的)传递真实用户IP的方式,其内容一般是:

1
X-Forwarded-For: real_client_ip, proxy1_ip, proxy2_ip

真实用户IP会被放在第一位

单独部署SpringBoot应用

当客户端直连SpingBoot时,可以直接简单的从HttpServletRequest中的getRemoteAddr()方法获取客户端IP

前端加一层Nginx代理

在Nginx中配置加入如下配置,会在http的请求头header中加入X-Forwarded-For信息

1
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

另外还有一种配置方式

1
proxy_set_header X-Forwarded-For $remote_addr;

两种方式的区别为$proxy_add_x_forwarded_for=$之前带的X-Forwarded-For信息, $remote_addr
Nginx在XFF信息中,把上一层的IP添加到了X-Forwarded-For信息的最后

所以正常情况下,从Nginx收到消息的XFF信息中,逗号分隔第一个ip为真实用户ip。
当用户带有人工添加XFF信息时,这些信息会被添加在XFF最前方,所以通过第一个IP来获取用户IP的方式不够合理。

在使用SpringBoot过程中,tomcat会默认使用RemoteIpValue类来获取真实用户IP,这个类会处理XFF信息,尝试从后往前获取真实用户IP,这个获取过程会尝试跳过内网ip地址(例如127、172)等,并从XFF信息中删除掉,最后设置到Request类的remoteAddr属性中。所以在应用层直接从HttpServletRequest中的getRemoteAddr()方法获取客户端IP。这种方式合理性在于,认为中间多层的Nginx代理信息,均为内网环境,第一个非内网IP为本应用群所接收到的外网IP,也就是对本应用群来讲的用户IP。

这里还需要考虑一个问题,假如用户在请求中带入虚假XFF信息,那么实际过程中会把XFF信息放在最前,而真实IP放在最后。所以SpringBoot中获取的仍是正确的。所以这里无需处理。

最终结论

无论是单独部署还是在nginx之后,应用都直接从HttpServletRequest中的getRemoteAddr()方法获取客户端IP,即可得到真实IP。

假如多层代理在不同网络环境中,该种方式只能获取到最后一片可用区所收到的外网IP。如果有需要可以关闭tomcat自动获取XFF信息开关,并手动解析XFF信息。注意需要在第一层代理中,清除过滤掉用户带的自定义XFF信息,保证链路可寻。

作者

LePhee

发布于

2019-10-24

更新于

2019-10-24

许可协议

评论