From 301eb9d7a22424af952b515d9bbed268952fd9a6 Mon Sep 17 00:00:00 2001 From: Amadeus Date: Sun, 26 May 2024 22:49:18 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E9=99=90=E6=B5=81=E6=93=8D?= =?UTF-8?q?=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/filter/FlowLimitFilter.java | 62 +++++++++++++++++++ src/main/java/com/example/utils/Const.java | 6 +- 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/example/filter/FlowLimitFilter.java diff --git a/src/main/java/com/example/filter/FlowLimitFilter.java b/src/main/java/com/example/filter/FlowLimitFilter.java new file mode 100644 index 0000000..39a3b61 --- /dev/null +++ b/src/main/java/com/example/filter/FlowLimitFilter.java @@ -0,0 +1,62 @@ +package com.example.filter; + +import com.example.entity.RestBean; +import com.example.utils.Const; +import jakarta.annotation.Resource; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpFilter; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.core.annotation.Order; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Component; + +import java.io.IOException; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +@Component +@Order(Const.ORDER_LIMIT) +public class FlowLimitFilter extends HttpFilter { + @Resource + StringRedisTemplate template; + + @Override + protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { + String address = request.getRemoteAddr(); + if (this.tryCount(address)){ + chain.doFilter(request,response); + }else { + this.writeBlockMessage(response); + } + + } + private void writeBlockMessage(HttpServletResponse response) throws IOException { + response.setStatus(HttpServletResponse.SC_FORBIDDEN); + response.setContentType("application/json;charset=uft-8"); + response.getWriter().write(RestBean.forbidden("操作频繁,请稍后再试").asJsonString()); + } + private boolean tryCount(String ip){ + synchronized (ip.intern()){ + if (Boolean.TRUE.equals(template.hasKey(Const.FLOW_LIMIT_BLOCK + ip))){ + return false; + } + return this.limitPeriodCheck(ip); + } + } + private boolean limitPeriodCheck(String ip){ + if (Boolean.TRUE.equals(template.hasKey(Const.FLOW_LIMIT_COUNTER + ip))) { + long increment = Optional.ofNullable(template.opsForValue().increment(Const.FLOW_LIMIT_COUNTER + ip)).orElse(0L) ; + if (increment > 10){ + template.opsForValue().set(Const.FLOW_LIMIT_BLOCK + ip , "" , 30 ,TimeUnit.SECONDS); + return false; + } + + }else { + template.opsForValue().set(Const.FLOW_LIMIT_COUNTER + ip ,"1" ,3 , TimeUnit.SECONDS ); + } + return true; + } + +} diff --git a/src/main/java/com/example/utils/Const.java b/src/main/java/com/example/utils/Const.java index e60413f..9810230 100644 --- a/src/main/java/com/example/utils/Const.java +++ b/src/main/java/com/example/utils/Const.java @@ -5,7 +5,11 @@ public class Const { public static final String VERIFY_EMAIL_LIMIT = "verify:email:limit:"; public static final String VERIFY_EMAIL_DATA = "verify:email:data:"; - public static final int ORDER_CORS = -102; + public static final int ORDER_LIMIT = -101; + + public static final String FLOW_LIMIT_COUNTER= "flow:counter:"; + public static final String FLOW_LIMIT_BLOCK= "flow:block:"; + }