当前位置: 首页 > news >正文

Java Spring Boot实现基于URL + IP访问频率限制

点击下载《Java Spring Boot实现基于URL + IP访问频率限制(源代码)》

1. 引言

在现代 Web 应用中,接口被恶意刷新或暴力请求是一种常见的攻击手段。为了保护系统资源,防止服务器过载或服务不可用,需要对接口的访问频率进行限制。本文将介绍如何使用 Spring Boot 实现基于 URL 和 IP 的访问频率限制,具体步骤包括:

  1. 使用拦截器拦截请求:在每个请求到达控制器之前进行拦截。

  2. 使用 Redis 存储访问记录:利用 Redis 的高性能特性来存储每个 IP 对每个 URL 的访问次数。

  3. 检测访问频率:判断 IP 在一定时间内对特定 URL 的访问次数是否超过限制。

  4. 禁用恶意 IP:如果超过限制,则将 IP 列入黑名单,禁止其后续访问。

2. 项目依赖

首先,在 pom.xml 中添加必要的依赖,包括 Spring Boot Web、Spring Boot Starter Data Redis 和 Lombok(用于简化代码)。

<!-- Spring Boot Starter Data Redis -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>3.4.1</version>
</dependency><!-- Lombok (可选,用于简化代码) -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional>
</dependency>

3. 配置 Redis

application.properties 中配置 Redis 连接信息:

server.port=8080
# Redis 配置
spring.data.redis.host=127.0.0.1
spring.data.redis.port=6379
spring.data.redis.database=0
# 可选:设置密码
# spring.data.redis.password=yourpassword

或在 application.yml 中配置Redis连接信息:

server:port: 8080spring:application:name: urlInterceptorDemodata:# redis 配置redis:# 地址host: 127.0.0.1# 端口,默认为6379port: 6379# 数据库索引database: 0# 密码password: "123456"# 连接超时时间timeout: 10s

4. 创建拦截器

创建一个拦截器 RateLimitInterceptor,用于拦截每个请求并执行访问频率限制逻辑。

package com.yyqq.urlinterceptordemo.Interceptor;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;import java.util.concurrent.TimeUnit;@Component
public class RateLimitInterceptor implements HandlerInterceptor {@Autowiredpublic RedisTemplate redisTemplate;// 访问频率限制:每个 IP 每个 URL 最多访问 100 次 / 分钟private static final int MAX_REQUESTS = 10;private static final int TIME_WINDOW = 60; // 秒@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String ip = getClientIP(request);String url = request.getRequestURI();String key = "rate_limit:" + url + ":" + ip;long count = redisTemplate.opsForValue().increment(key, 1);if (count == 1) {// 设置键的过期时间为 TIME_WINDOW 秒redisTemplate.expire(key, TIME_WINDOW, TimeUnit.SECONDS);}if (count > MAX_REQUESTS) {response.setStatus(HttpServletResponse.SC_FORBIDDEN);response.setContentType("text/html;charset=UTF-8");response.getWriter().write("请求过于频繁,请稍后再试。");return false;}return true;}private String getClientIP(HttpServletRequest request) {String ip = request.getHeader("X-Forwarded-For");if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("Proxy-Client-IP");}if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("WL-Proxy-Client-IP");}if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();}return ip;}
}

代码说明

  • RedisTemplate:用于与 Redis 进行交互。
  • MAX_REQUESTS 和 TIME_WINDOW:定义每个 IP 在每个 URL 上的最大访问次数和时间窗口(60 秒)。
  • preHandle 方法
    • 获取客户端 IP 和请求的 URL。
    • 构建 Redis 键,例如 rate_limit:/api/data:192.168.1.1
    • 使用 increment 方法对键进行递增,并设置过期时间。
    • 如果访问次数超过 MAX_REQUESTS,则返回 403 状态码,并返回错误信息。
  • getClientIP 方法:获取客户端的真实 IP,处理代理和负载均衡的情况。

5. 注册拦截器

创建一个配置类 WebConfig,将拦截器注册到 Spring MVC 中。

package com.yyqq.urlinterceptordemo.config;import com.yyqq.urlinterceptordemo.Interceptor.RateLimitInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate RateLimitInterceptor rateLimitInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(rateLimitInterceptor).addPathPatterns("/**") // 拦截所有路径.excludePathPatterns("/error"); // 排除错误路径}
}

代码说明

  • addInterceptors 方法:将自定义的拦截器添加到拦截器链中,并指定拦截的路径模式。
  • addPathPatterns("/")**:拦截所有路径。
  • excludePathPatterns(“/error”):排除错误路径,避免拦截器影响错误处理。

6. 创建控制器

创建一个简单的控制器 DemoController,包含一个示例接口用于测试。

package com.yyqq.urlinterceptordemo.controller;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/test")
public class DemoController {@GetMapping("/getData")public String getData() {return "这是数据接口,现在访问正常!";}
}

8. 测试

启动 Spring Boot 应用后,可以进行以下测试:

1.正常访问

  • 访问 http://localhost:8080/test/getData,应返回 “这是数据接口,现在访问正常!”。

  • 多次快速刷新,访问次数达到 10 次后,应返回 “请求过于频繁,请稍后再试。”,并返回 403 状态码。
    在这里插入图片描述

2.禁用 IP

  • 在达到限制后,等待一段时间(60 秒),再次访问应恢复正常。

    在这里插入图片描述

9. 总结

通过结合使用 Spring Boot 拦截器和 Redis,本文实现了一种基于 URL 和 IP 的访问频率限制机制。这种机制能够有效地防止接口被恶意刷新和暴力请求,保护系统资源,提高应用的安全性和稳定性。在实际应用中,可以根据具体需求调整访问频率限制的参数,如最大访问次数和时间窗口。此外,还可以结合其他安全措施,如 IP 黑名单、验证码等,进一步增强系统的防护能力。

点击下载《Java Spring Boot实现基于URL + IP访问频率限制(源代码)》

http://www.lryc.cn/news/517095.html

相关文章:

  • C4D2025 win版本安装完无法打开,提示请将你的maxon App更新至最新版本,如何解决
  • 微信小程序实现登录注册
  • SpringBoot环境和Maven配置
  • 大语言模型训练所需的最低显存,联邦大语言模型训练的传输优化技术
  • 1.07 标准IO
  • 恒压恒流原边反馈控制芯片 CRE6289F
  • Java中线程中断的几种方式,你了解吗?
  • Tesseract5.4.0自定义LSTM训练
  • centOS7
  • HTML5 弹跳动画(Bounce Animation)详解
  • 4.1.3 串
  • 国产编辑器EverEdit - 两种删除空白行的方法
  • 1月7日星期二今日早报简报微语报早读
  • 随机置矩阵列为0[矩阵乘法pytorch版]
  • C# 中mysql数据库,已经在原有数据库升级数据库脚本,去管理可以一次,和多次执行的,nuget包
  • PCL 分段线性函数
  • 王静波页岩气:工厂蜕变的创业传奇
  • php反序列化 ctf例题演示 框架安全(TP,Yii,Laravel) phpggc生成框架利用pop
  • Koi技术教程-Tauri基础教程-第二节 Tauri的核心概念上
  • 入门网络安全工程师要学习哪些内容【2025年寒假最新学习计划】
  • vulnhub靶场【DC系列】之5
  • 前端面试题合集
  • 基于RK3568/RK3588大车360度环视影像主动安全行车辅助系统解决方案,支持ADAS/DMS
  • 基于 GEE Sentinel-1 数据集提取水体
  • Python判断、循环练习
  • 【简博士统计学习方法】第1章:4. 模型的评估与选择
  • 解密Navicat密码(Java)
  • 某聘__zp_stoken__参数逆向还原
  • 【数据可视化-11】全国大学数据可视化分析
  • 声音是如何产生的