1、 API接口防刷 1.1、概念
顾名思义,就是要实现某个接口在某段时间内只能让某人访问指定次数,超出次数,就不让访问了 1.2、原理
在请求的时候,服务器通过 Redis 记录下你请求的次数,如果次数超过限制就不给访问在 Redis 保存的 Redis 是有时效性的,过期就会删除
1.3、目的
主要防止短时间接口被大量调用(攻击),出现系统崩溃和系统爬虫问题,提升服务的可用性
1.4、实现方案介绍
1. 拦截器+自定义注解+Redis
2. AOP+自定义注解+Redis
2、方案一
好,接下来我们直接实战编码,运用到项目中的话,非常实用,使用起来也非常方便,下面是我们需要
写的几个核心类
1. 自定义注解
2. 拦截器(核心)
3. Redis配置类(设置序列化用)
2.1、自定义注解
2.2、拦截器
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.concurrent.TimeUnit;
/**
* 防刷限流的拦截器
* @author wujiangbo
* @date 2022-08-23 18:39
*/ @Component
public class RateLimitInterceptor implements HandlerInterceptor {
@Resource private RedisTemplate<String, Integer> redisTemplate;
@Override
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
// 如果请求的是方法,则需要做校验
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
// 获取目标方法上是否有指定注解
RateLimit rateLimit = handlerMethod.getMethodAnnotation(RateLimit.class);
if (rateLimit == null) {
//说明目标方法上没有 RateLimit 注解
return true;
}
//代码执行到此,说明目标方法上有 RateLimit 注解,所以需要校验这个请求是不是在刷接口
// 获取请求IP地址
String ip = getIpAddr(request);
// 请求url路径
String uri = request.getRequestURI();
//存到redis中的key
String key = "RateLimit:" + ip + ":" &#