深度揭秘!Spring Boot 3 拦截器获取请求 IP 的机制及实战应用

在互联网大厂后端开发的复杂场景中,精准获取请求 IP 地址是众多功能实现的基础,比如安全防护、用户行为分析、个性化服务定制等。今天,就带大家深入探索 Spring Boot 3 拦截器获取请求 IP 的机制,助力各位开发者在实际项目中更加游刃有余地应对相关挑战。

Spring Boot 3 中获取请求 IP 的常规方式

在 Spring Boot 3 的开发框架下,我们通常会借助HttpServletRequest对象来获取请求的 IP 地址。在拦截器的实现逻辑里,获取 IP 的代码看似简单:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
public class IPInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String ipAddress = request.getRemoteAddr();
        // 这里可以添加对IP地址的处理逻辑,比如记录日志、校验等
        return true;
    }
}

在上述代码中,通过request.getRemoteAddr()方法,就能轻松获取到请求的 IP 地址。然而,这看似简单的一行代码,在实际的生产环境中,却可能隐藏着诸多陷阱。

生产环境下的复杂情况

当应用部署在反向代理(如 Nginx)的架构之后,情况就变得复杂起来。此时,request.getRemoteAddr()方法获取到的并非真实的客户端 IP 地址,而是反向代理服务器的 IP 地址。这是因为在请求的传递过程中,经过反向代理时,原始的客户端 IP 信息被 “隐藏” 了。为了获取到真实的客户端 IP,我们需要从 HTTP 头中寻找线索,其中,X-Forwarded-For头信息就是关键所在。

X-Forwarded-For头信息会记录请求经过的代理服务器列表,最左边的 IP 地址即为客户端的真实 IP。例如,当请求依次经过客户端、Nginx 反向代理、应用服务器时,X-Forwarded-For头信息可能是这样的格式:client_ip, nginx_ip。所以,在这种情况下,我们获取真实客户端 IP 的代码需要做出相应调整:

String xfHeader = request.getHeader("X-Forwarded-For");
if (xfHeader != null) {
    ipAddress = xfHeader.split(",")[0].trim();
}

这段代码的逻辑是,先获取X-Forwarded-For头信息,如果不为空,就按照逗号进行分割,取最左边的 IP 地址,也就是客户端的真实 IP。

完整的拦截器配置与实现

要让获取 IP 的功能在整个应用中生效,还需要完成拦截器的配置。在 Spring Boot 3 中,我们通过实现WebMvcConfigurer接口来配置拦截器。具体代码如下:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new IPInterceptor()).addPathPatterns("/**");
    }
}

在上述配置类中,addInterceptor(new IPInterceptor())表示添加我们自定义的IPInterceptor拦截器,而addPathPatterns("/**")则表示该拦截器对所有的请求路径都生效。

基于 IP 地址的高级应用场景

IP 白名单与黑名单功能实现

在安全防护领域,基于 IP 地址的访问控制是非常重要的手段。实现 IP 白名单功能时,我们可以在拦截器中校验获取到的 IP 地址是否在预先设定的白名单列表中。若在白名单内,则允许请求通过;否则,拒绝请求。

实现代码示例如下:

private final List<String> whiteListIps = Arrays.asList("192.168.1.100", "10.0.0.1");
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    String ipAddress = getClientIp(request);
    if (whiteListIps.contains(ipAddress)) {
        return true;
    } else {
        response.getWriter().write("Access Denied");
        return false;
    }
}
private String getClientIp(HttpServletRequest request) {
    String xfHeader = request.getHeader("X-Forwarded-For");
    if (xfHeader != null) {
        return xfHeader.split(",")[0].trim();
    }
    return request.getRemoteAddr();
}

同理,实现 IP 黑名单功能时,只需判断 IP 地址是否在黑名单列表中,若在,则拒绝请求。

基于 IP 的用户行为分析与个性化服务

在用户行为分析方面,通过获取用户的 IP 地址,可以分析出用户的地域分布、访问频率等信息。例如,我们可以统计不同地区用户对应用内不同功能的使用频率,从而为产品优化提供数据支持。

在个性化服务方面,根据用户的 IP 地址判断其所在地区,为用户提供本地化的服务或推荐内容。比如,对于位于北京地区的用户,推送与北京相关的资讯、活动等。

总结

通过本文,我们深入了解了 Spring Boot 3 拦截器获取请求 IP 的机制,以及在生产环境中应对复杂情况的方法,还探讨了基于 IP 地址的高级应用场景。在实际的互联网大厂后端开发工作中,熟练掌握这些知识,能够帮助我们更好地构建安全、高效、个性化的应用服务。

随着互联网技术的不断发展,网络环境会变得更加复杂多样,获取请求 IP 以及基于 IP 的相关功能实现可能会面临新的挑战。但只要我们深入理解底层原理,不断学习和探索新的技术与方法,就一定能够从容应对,为用户带来更优质的服务体验。

各位互联网大厂的后端开发同行们,希望本文能给你们在日常开发中带来帮助,也欢迎大家在评论区分享自己在获取请求 IP 方面的经验与心得,让我们共同进步!

相关文章

一文搞懂Nginx反向代理、负载均衡的原理与配置

大家好,我是IT售前工程师Bernie。本文重点介绍反向代理、正向代理的区别,以及Nginx的反向代理、负载均衡原理。为什么需要代理服务器当一个网站并发量特别小,用户特别少的时候,我们在服务器上放一个...

Nginx反向代理之proxy_set_header指令

该指令可以更改Nginx服务器接收到的客户端请求的请求头信息,然后 将新的请求头发送给代理的服务器proxy_set_header是什么意思呢?这里涉及到客户端,代理服务器,被代理的服务器一般都是客户...

Nginx之反向代理与负载均衡

今天我们一起学习一下反向代理Nginx的反向代理分为http七层的反向代理和四层的反向代理(stream)。在学习反向代理的过程中会引出两个概念:1. 负载均衡2. 缓存一个请求的顺序是先到达Ngin...

告别繁琐配置,Nginx Proxy Manager:你的家庭网络反向代理利器

在家庭网络中搭建各种服务,如个人博客、文件共享、影音中心等,已经成为许多技术爱好者的日常。然而,配置反向代理和管理 SSL 证书往往让人望而却步。今天,我们要介绍的开源项目 Nginx Proxy M...

java 面试题:如何实现跨域?

在 Java 中实现跨域(Cross-Origin Resource Sharing,CORS)主要有以下几种方式,具体选择取决于应用场景和架构设计:一、前端代理(开发环境)在开发环境中,可通过前端脚...