记录目的
开发中的需求是,免登时限制同一个IP用户不要在一段时间内不能频繁提交表单
引言
在现代Web应用中,防止恶意爬虫、DDoS攻击和API滥用是至关重要的。为了实现这一目标,一种常见的策略是对特定IP地址的请求频率进行限制。本文将详细介绍如何在Spring Boot项目中利用Redis来实现这一功能。
架构设计
我们的解决方案基于以下组件:
- Spring Boot:提供快速开发Web应用的能力。
- Spring MVC:用于处理HTTP请求和响应。
- Lombok:简化Java对象的代码编写。
- Redis:作为存储和计算访问频率的后端数据库。
- Fastjson:用于JSON数据的序列化和反序列化。
实现步骤
-
引入依赖
首先,确保你的
pom.xml
文件中包含了Spring Boot、Spring Data Redis和Lombok的依赖。 -
配置Redis连接
在
application.properties
中配置Redis服务器的连接信息。 -
创建Redis工具类
我们需要一个工具类来处理与Redis的交互,包括设置和获取IP访问时间戳。
@Component public class RedisThrottleUtils { private final RedisTemplate<String, Long> redisTemplate; public boolean isRequestAllowed(String ip) { String key = "throttle:" + ip; ValueOperations<String, Long> valueOps = redisTemplate.opsForValue(); long currentTime = System.currentTimeMillis(); long timeFrame = TimeUnit.MINUTES.toMillis(1); Long lastRequestTime = valueOps.get(key); if (lastRequestTime != null && (currentTime - lastRequestTime) < timeFrame) { return false; } valueOps.set(key, currentTime, timeFrame, TimeUnit.MILLISECONDS); return true; } }
-
实现拦截器
创建一个拦截器,用于检查每个请求是否满足访问频率要求。
@Component public class IPRequestThrottleInterceptor implements HandlerInterceptor { private final RedisThrottleUtils redisThrottleUtils; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String clientIP = request.getRemoteAddr(); if (!redisThrottleUtils.isRequestAllowed(clientIP)) { AjaxResult error = AjaxResult.error("请求过于频繁,请稍后再试"); renderString(response, JSONObject.toJSONString(error)); return false; } return true; } private static void renderString(HttpServletResponse response, String string) { try { response.setContentType("application/json;charset=UTF-8"); PrintWriter writer = response.getWriter(); writer.print(string); writer.flush(); writer.close(); } catch (IOException e) { throw new RuntimeException(e); } } }
-
配置WebMvcConfigurer
最后,我们需要配置Spring MVC以使用我们的拦截器。
@Configuration @RequiredArgsConstructor public class ResourcesConfig implements WebMvcConfigurer { private final IPRequestThrottleInterceptor ipRequestThrottleInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(ipRequestThrottleInterceptor) .addPathPatterns("/content/appeal/noLoginSubmit"); } }
总结
通过上述步骤,我们成功地在Spring Boot项目中实现了基于Redis的IP访问频率限制。这种方法不仅能够有效防止恶意行为,还保持了系统的高可用性和响应性。希望这篇博客能帮助你在自己的项目中实现类似的功能。