欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > Springboot中基于 IP 地址的请求速率限制拦截器

Springboot中基于 IP 地址的请求速率限制拦截器

2024/10/23 13:31:33 来源:https://blog.csdn.net/a983677218/article/details/142996790  浏览:    关键词:Springboot中基于 IP 地址的请求速率限制拦截器

       基于 IP 地址的请求速率限制拦截器,使用了 Bucket4j 库来管理请求的令牌桶。下面是对代码的详细解释,以及如何在触发请求拒绝时将 IP 地址加入黑名单的实现。  

      导入依赖

        <dependency><groupId>com.github.vladimir-bukhtoyarov</groupId><artifactId>bucket4j-core</artifactId><version>6.0.2</version></dependency>

      RateLimitInterceptor拦截器类

import io.github.bucket4j.Bandwidth;
import io.github.bucket4j.Bucket;
import io.github.bucket4j.Bucket4j;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.Duration;
import java.util.concurrent.ConcurrentHashMap;@Slf4j
public class RateLimitInterceptor implements HandlerInterceptor {private final Bandwidth limit = Bandwidth.simple(100, Duration.ofMinutes(1));private final ConcurrentHashMap<String, Bucket> buckets = new ConcurrentHashMap<>();@Autowiredprivate RedisTemplate<String, String> redisTemplate; // Redis 模板@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {String ip = request.getRemoteAddr();log.info("当前访问ip: {}", ip);// 检查 IP 是否在黑名单中if (isBlacklisted(ip)) {response.setStatus(403); // 返回 403 状态码,表示禁止访问return false; // 拒绝请求}Bucket bucket = buckets.computeIfAbsent(ip, key -> Bucket4j.builder().addLimit(limit).build());if (bucket.tryConsume(1)) {return true; // 允许请求} else {// 将 IP 加入黑名单blacklistIp(ip);response.setStatus(429); // 返回 429 状态码return false; // 拒绝请求}}private boolean isBlacklisted(String ip) {// 检查 Redis 中是否存在该 IPreturn redisTemplate.hasKey("blacklist:" + ip);}private void blacklistIp(String ip) {// 将 IP 加入黑名单,设置过期时间为 1 小时redisTemplate.opsForValue().set("blacklist:" + ip, "true", Duration.ofHours(1));}
}

导入依赖:
Bucket4j:用于实现令牌桶算法的库。
HandlerInterceptor:Spring MVC 的拦截器接口,用于在请求处理之前和之后执行一些操作。
ConcurrentHashMap:用于存储每个 IP 地址对应的令牌桶,支持并发访问。
类定义:
RateLimitInterceptor 类实现了 HandlerInterceptor 接口。
带宽定义:
limit:定义了一个带宽限制,设置为每分钟允许 100 次请求。
桶存储:
buckets:使用 ConcurrentHashMap 存储每个 IP 地址对应的令牌桶。
请求处理:
preHandle 方法在请求处理之前被调用。
获取请求的 IP 地址。
使用 computeIfAbsent 方法获取或创建对应 IP 的桶。
尝试消耗一个令牌,如果成功,则允许请求继续;如果失败,则返回 429 状态码,表示请求过多。

RedisTemplate:

使用 RedisTemplate 来与 Redis 进行交互,检查和存储黑名单。
黑名单检查:

在 preHandle 方法中,首先检查请求的 IP 是否在黑名单中。如果在黑名单中,返回 403 状态码,拒绝请求。
黑名单添加:

如果请求被拒绝(即超过速率限制),调用 blacklistIp 方法将该 IP 加入黑名单,并设置过期时间为 1 小时。
黑名单检查方法:

isBlacklisted 方法用于检查 IP 是否在黑名单中。
通过这些修改,您可以有效地管理请求速率,并在触发拒绝请求时将 IP 地址加入黑名单,从而防止恶意请求。

web配置文件中注册拦截器

	/*** 注册拦截器* @Param [registry]*/@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 注册jwt拦截器registry.addInterceptor(new JWTInterceptor()).excludePathPatterns("/user/register", "/user/login", "/user/info", "/user/logout", ).//请求放行addPathPatterns("/**");// 注册速率限制拦截器registry.addInterceptor(new RateLimitInterceptor());}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com