【SpringBoot】如何获取请求的IP地址?
在 Java Web 应用中,想要在接口中获取到发送请求的客户端 IP 地址,需要依赖请求对象 —— HttpServletRequest。
那么,首先就是要先获取到请求的对象。
在 Spring Boot 中,只需在接口方法上加上 HttpServletRequest 或 HttpServletResponse 参数,Spring Boot 就会自动绑定这两个对象,然后可以直接使用。如果你的方法有其他参数,只需把这两个加到后面即可。例如:
|
这是最常用的一种方法,当然除了这种方式,在 Spring Boot 中还可以使用注解 @Autowired
注入或通过 RequestContextHolder 来获取请求对象,这里就不展开叙述了。
在得到请求对象 HttpServletRequest 对象后,一般的,我们可以使用 request.getRemoteAddr()
来获取到客户端对应的 IP 地址。
但是,如果使用了 Nginx 等反向代理软件,则不能只简单地通过上述代码来获取 IP;并且,如果使用了多级反向代理的话,那么在获取 X-Forwarded-For 的值时,得到的应是一串 IP 地址,此种情况下,X-Forwarded-For 中第一个非 unknown
的有效 IP 字符串,则为真实 IP 地址。
获取IP的工具类
public class IpUtil { |
字段解释
X-Forwarded-For
格式为 X-Forwarded-For:client1,proxy1,proxy2
,一般情况下,第一个 ip 为客户端真实 ip,后面的为经过的代理服务器 ip。现在大部分的代理都会加上这个请求头。
Proxy-Client-IP/WL- Proxy-Client-IP
这个一般是经过 apache http 服务器的请求才会有,用 apache http 做代理时一般会加上 Proxy-Client-IP
请求头,而 WL-Proxy-Client-IP
是他的 weblogic 插件加上的请求头。
需要注意几点:
- 这些请求头都不是 http 协议里的标准请求头,也就是说这是各个代理服务器自己规定的表示客户端地址的请求头。如果哪天有一个代理服务器软件用
xxx-client-ip
这个请求头代表客户端请求,那上面的代码就不行了。 - 这些请求头不是代理服务器一定会带上的,网络上的很多匿名代理就没有这些请求头,所以获取到的客户端 ip 不一定是真实的客户端 ip。代理服务器一般都可以自定义请求头设置。
- 即使请求经过的代理都会按自己的规范附上代理请求头,上面的代码也不能确保获得的一定是客户端 ip。不同的网络架构,判断请求头的顺序是不一样的。
- 最重要的一点,请求头都是可以伪造的。如果一些对客户端校验较严格的应用(比如投票)要获取客户端 ip,应该直接使用
request.getRemoteAddr()
,虽然获取到的可能是代理的 ip 而不是客户端的 ip,但这个获取到的 ip 基本上是不可能伪造的,也就杜绝了刷票的可能。
如何使用
|
Nginx配置
在配置里加上:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |
参考链接
Java 实战系列·获取请求 IP 地址-腾讯云开发者社区-腾讯云 (tencent.com)
通过 HttpServletRequest 获取客户端 IP 地址 - CoderGeshu - 博客园 (cnblogs.com)