From 877d20a6b39317e96548177699251a2f95728041 Mon Sep 17 00:00:00 2001
From: TanYibin <5491541@qq.com>
Date: Mon, 12 Jun 2023 16:54:40 +0800
Subject: [PATCH] 访问限制添加

---
 huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/LoginController.java              |  4 ----
 huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysDepartController.java          | 36 +++++++++++++++++++++++++-----------
 huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysDictController.java            | 36 +++++++++++++++++++++++++-----------
 huaheng-wms-core/src/main/java/org/jeecg/modules/system/service/impl/SysGatewayRouteServiceImpl.java | 18 +++++++++---------
 huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/controller/TestController.java        | 18 ++++++++++++------
 huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengRedisUtil.java                                 | 13 ++++++-------
 huaheng-wms-core/src/main/java/org/jeecg/utils/config/InterceptorAdapterConfig.java                  | 20 ++++++++++++++++++++
 huaheng-wms-core/src/main/java/org/jeecg/utils/interceptor/AccessLimit.java                          | 17 +++++++++++++++++
 huaheng-wms-core/src/main/java/org/jeecg/utils/interceptor/AccessLimitInterceptor.java               | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 178 insertions(+), 48 deletions(-)
 create mode 100644 huaheng-wms-core/src/main/java/org/jeecg/utils/config/InterceptorAdapterConfig.java
 create mode 100644 huaheng-wms-core/src/main/java/org/jeecg/utils/interceptor/AccessLimit.java
 create mode 100644 huaheng-wms-core/src/main/java/org/jeecg/utils/interceptor/AccessLimitInterceptor.java

diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/LoginController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/LoginController.java
index 04ab0b9..39ef544 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/LoginController.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/LoginController.java
@@ -53,7 +53,6 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Bean;
 import org.springframework.core.io.DefaultResourceLoader;
 import org.springframework.core.io.ResourceLoader;
-import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.util.FileCopyUtils;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -109,9 +108,6 @@ public class LoginController {
     private ISysTenantService sysTenantService;
 
     @Autowired
-    public RedisTemplate<String, ?> redisTemplate;
-
-    @Autowired
     private ISysDictService sysDictService;
 
     @Autowired
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysDepartController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysDepartController.java
index 7d5978e..e083569 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysDepartController.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysDepartController.java
@@ -1,18 +1,25 @@
 package org.jeecg.modules.system.controller;
 
-import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import lombok.extern.slf4j.Slf4j;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
 import org.apache.commons.lang3.StringUtils;
 import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
-import org.apache.shiro.authz.annotation.RequiresRoles;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.constant.CacheConstant;
 import org.jeecg.common.constant.CommonConstant;
 import org.jeecg.common.system.query.QueryGenerator;
-import org.jeecg.utils.HuahengJwtUtil;
 import org.jeecg.common.system.vo.LoginUser;
 import org.jeecg.common.util.ImportExcelUtil;
 import org.jeecg.common.util.YouBianCodeUtil;
@@ -24,6 +31,7 @@ import org.jeecg.modules.system.model.SysDepartTreeModel;
 import org.jeecg.modules.system.service.ISysDepartService;
 import org.jeecg.modules.system.service.ISysUserDepartService;
 import org.jeecg.modules.system.service.ISysUserService;
+import org.jeecg.utils.HuahengJwtUtil;
 import org.jeecgframework.poi.excel.ExcelImportUtil;
 import org.jeecgframework.poi.excel.def.NormalExcelConstants;
 import org.jeecgframework.poi.excel.entity.ExportParams;
@@ -32,15 +40,21 @@ import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.multipart.MultipartHttpServletRequest;
 import org.springframework.web.servlet.ModelAndView;
 
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.util.*;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+
+import lombok.extern.slf4j.Slf4j;
 
 /**
  * <p>
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysDictController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysDictController.java
index 4f7b0df..8e198a3 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysDictController.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/controller/SysDictController.java
@@ -1,14 +1,18 @@
 package org.jeecg.modules.system.controller;
 
-import com.alibaba.fastjson.JSON;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import lombok.extern.slf4j.Slf4j;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
 import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
-import org.apache.shiro.authz.annotation.RequiresRoles;
 import org.jeecg.common.api.vo.Result;
 import org.jeecg.common.constant.CacheConstant;
 import org.jeecg.common.constant.CommonConstant;
@@ -36,14 +40,24 @@ import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 import org.springframework.web.multipart.MultipartHttpServletRequest;
 import org.springframework.web.servlet.ModelAndView;
 
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.util.*;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+import lombok.extern.slf4j.Slf4j;
 
 /**
  * <p>
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/service/impl/SysGatewayRouteServiceImpl.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/service/impl/SysGatewayRouteServiceImpl.java
index 82a2e24..101bb50 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/system/service/impl/SysGatewayRouteServiceImpl.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/system/service/impl/SysGatewayRouteServiceImpl.java
@@ -1,11 +1,7 @@
 package org.jeecg.modules.system.service.impl;
 
-import cn.hutool.core.util.ObjectUtil;
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import lombok.extern.slf4j.Slf4j;
+import java.util.List;
+
 import org.jeecg.common.base.BaseMap;
 import org.jeecg.common.constant.CacheConstant;
 import org.jeecg.common.constant.GlobalConstants;
@@ -18,9 +14,13 @@ import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+
+import cn.hutool.core.util.ObjectUtil;
+import lombok.extern.slf4j.Slf4j;
 
 /**
  * @Description: gateway路由管理
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/controller/TestController.java b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/controller/TestController.java
index aa39b51..47d7af5 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/controller/TestController.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/modules/wms/framework/controller/TestController.java
@@ -12,7 +12,9 @@ import org.jeecg.modules.system.service.ISysDataLogService;
 import org.jeecg.modules.wms.receipt.receiptContainerHeader.entity.ReceiptContainerDetail;
 import org.jeecg.utils.HuahengRedisUtil;
 import org.jeecg.utils.config.ApplicationConfig;
+import org.jeecg.utils.interceptor.AccessLimit;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -20,6 +22,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.RestController;
 
 import com.alibaba.fastjson.JSON;
+import com.google.common.util.concurrent.RateLimiter;
 
 import cn.monitor4all.logRecord.context.LogRecordContext;
 import lombok.extern.slf4j.Slf4j;
@@ -39,10 +42,15 @@ public class TestController extends HuahengBaseController {
 
     @Autowired
     private ISysDataLogService sysDataLogService;
-    
+
     @Autowired
     private ApplicationConfig applicationConfig;
-    
+
+//    @AccessLimit(seconds = 1, maxCount = 10)
+    @PostMapping(value = "/testLimiter")
+    public Result<?> testLimiter(@RequestBody Map<String, String> paramMap) {
+        return Result.OK();
+    }
 
 //    @ApiLogger(apiName = "API接口第三方Token校验测试", from = "TEST")
 //    @ResponseBody
@@ -69,9 +77,7 @@ public class TestController extends HuahengBaseController {
         LogRecordContext.putVariable("locationCode", "100001");// 操作日志收集
         LogRecordContext.putVariable("receiptContainerDetailList", receiptContainerDetailList);// 操作日志收集
         LogRecordContext.putVariable("extraJsonString", JSON.toJSONString(receiptContainerDetailList));// 操作日志收集
-        
-        
-        
+
 //        String testString = "我是testString1";
 //        LogRecordContext.putVariable("testString1", testString);
 //        testString = "我是testString2";
@@ -146,7 +152,7 @@ public class TestController extends HuahengBaseController {
 //        LogRecordContext.putVariable("result", result);
 //        return result;
     }
-    
+
     @ResponseBody
     @PostMapping(value = "/deleteRedisKey")
     public Result<?> deleteRedisKey(@RequestBody Map<String, String> paramMap, HttpServletRequest request) throws InterruptedException {
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengRedisUtil.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengRedisUtil.java
index ada81bf..17ea09f 100644
--- a/huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengRedisUtil.java
+++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/HuahengRedisUtil.java
@@ -1,13 +1,11 @@
 package org.jeecg.utils;
 
-import java.util.List;
-import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
 import javax.annotation.Nonnull;
+import javax.annotation.Resource;
 
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Component;
 import org.springframework.util.StringUtils;
 
@@ -25,8 +23,8 @@ import lombok.extern.slf4j.Slf4j;
 @Component
 public class HuahengRedisUtil {
 
-    @Autowired
-    private StringRedisTemplate redisTemplate;
+    @Resource
+    private RedisTemplate<String, String> redisTemplate;
 
     private static String toJson(Object obj) {
         if (obj == null) {
@@ -99,7 +97,7 @@ public class HuahengRedisUtil {
             log.error("操作缓存异常:key:{}", key, e);
         }
     }
-    
+
     /**
      * 设置key,value 无过期时间
      * @author           TanYibin
@@ -288,4 +286,5 @@ public class HuahengRedisUtil {
         }
         return false;
     }
+
 }
\ No newline at end of file
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/config/InterceptorAdapterConfig.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/config/InterceptorAdapterConfig.java
new file mode 100644
index 0000000..3b8be4c
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/config/InterceptorAdapterConfig.java
@@ -0,0 +1,20 @@
+package org.jeecg.utils.config;
+
+import org.jeecg.utils.interceptor.AccessLimitInterceptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
+
+@Configuration
+public class InterceptorAdapterConfig extends WebMvcConfigurationSupport {
+    @Autowired
+    private AccessLimitInterceptor accessLimitInterceptor;
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        // 注册自己的拦截器并设置拦截的请求路径
+        registry.addInterceptor(accessLimitInterceptor).addPathPatterns("/**");
+        super.addInterceptors(registry);
+    }
+}
\ No newline at end of file
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/interceptor/AccessLimit.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/interceptor/AccessLimit.java
new file mode 100644
index 0000000..c41fb3d
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/interceptor/AccessLimit.java
@@ -0,0 +1,17 @@
+package org.jeecg.utils.interceptor;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(value = {ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AccessLimit {
+
+    // 单位时间
+    int seconds();
+
+    // 最大次数
+    int maxCount();
+}
\ No newline at end of file
diff --git a/huaheng-wms-core/src/main/java/org/jeecg/utils/interceptor/AccessLimitInterceptor.java b/huaheng-wms-core/src/main/java/org/jeecg/utils/interceptor/AccessLimitInterceptor.java
new file mode 100644
index 0000000..4709252
--- /dev/null
+++ b/huaheng-wms-core/src/main/java/org/jeecg/utils/interceptor/AccessLimitInterceptor.java
@@ -0,0 +1,64 @@
+package org.jeecg.utils.interceptor;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.jeecg.common.exception.JeecgBootException;
+import org.jeecg.utils.HuahengRedisUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import com.alibaba.fastjson.JSON;
+
+import cn.hutool.extra.servlet.ServletUtil;
+import io.micrometer.core.instrument.util.JsonUtils;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 拦截器限流
+ * @author     TanYibin
+ * @createDate 2023年6月12日
+ */
+
+@Slf4j
+@Component
+public class AccessLimitInterceptor extends HandlerInterceptorAdapter {
+
+    @Autowired
+    private HuahengRedisUtil huahengRedisUtil;
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        if (handler instanceof HandlerMethod) {
+            HandlerMethod hm = (HandlerMethod)handler;
+            // 获取方法中的注解,看是否有该注解
+            AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);
+            if (accessLimit == null) {
+                return true;
+            }
+            int seconds = accessLimit.seconds();
+            int maxCount = accessLimit.maxCount();
+            String requestURI = request.getRequestURI();
+            log.info(ServletUtil.getBody(request));
+            Integer count = huahengRedisUtil.get(requestURI, Integer.class);
+            if (count == null) {
+                // 第一次访问
+                huahengRedisUtil.set(requestURI, 1, seconds);
+            } else if (count < maxCount) {
+                // 加1
+                huahengRedisUtil.incr(requestURI, seconds);
+            } else {
+                log.error("{},超出访问频次限制。限制频次:{}次/{}秒", requestURI, maxCount, seconds);
+                throw new JeecgBootException("超出访问频次限制");
+            }
+        }
+        return true;
+    }
+}
\ No newline at end of file
--
libgit2 0.22.2