Bläddra i källkod

单独导入修复

lzzz 5 månader sedan
förälder
incheckning
c4f3f4bc0e

+ 13 - 0
application.yaml

@@ -7,6 +7,16 @@ spring:
     username: root
     password: eai123456
     url: jdbc:mysql://8.130.28.19:3306/eai?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&allowPublicKeyRetrieval=true
+    hikari:
+      maximum-pool-size: 30
+      minimum-idle: 10
+      connection-timeout: 10000
+      validation-timeout: 3000
+      idle-timeout: 600000
+      # Keep maxLifetime shorter than MySQL wait_timeout to avoid stale pooled connections.
+      max-lifetime: 240000
+      keepalive-time: 120000
+      leak-detection-threshold: 30000
 #    url: jdbc:mysql://127.0.0.1:3306/eai?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&allowPublicKeyRetrieval=true
   data:
     mongodb:
@@ -45,6 +55,9 @@ jwt:
   secret: UenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRW
   issuer: eai
   expiration: 86400
+  portal-sync:
+    enabled: true
+    throttle-seconds: 60
 
 
 aliyun:

+ 40 - 2
src/main/java/com/njuzr/eaibackend/config/JWTAuthenticationFilter.java

@@ -12,6 +12,8 @@ import jakarta.servlet.ServletException;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.security.authentication.CredentialsExpiredException;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.context.SecurityContextHolder;
@@ -21,6 +23,7 @@ import org.springframework.web.filter.OncePerRequestFilter;
 
 import java.io.IOException;
 import java.util.Map;
+import java.util.concurrent.TimeUnit;
 
 /**
  * @author: Leonezhurui
@@ -35,13 +38,24 @@ public class JWTAuthenticationFilter extends OncePerRequestFilter {
     private final JWTTokenUtil jwtTokenUtil;
     private final MyUserDetailService userDetailService;
     private final UserService userService;
+    private final RedisTemplate<String, Object> redisTemplate;
+
+    @Value("${jwt.portal-sync.enabled:true}")
+    private boolean portalSyncEnabled;
+
+    @Value("${jwt.portal-sync.throttle-seconds:60}")
+    private long portalSyncThrottleSeconds;
 
     private final MyAuthenticationEntryPoint authenticationEntryPoint = new MyAuthenticationEntryPoint();
 
-    public JWTAuthenticationFilter(JWTTokenUtil jwtTokenUtil, MyUserDetailService userDetailService, UserService userService) {
+    public JWTAuthenticationFilter(JWTTokenUtil jwtTokenUtil,
+                                   MyUserDetailService userDetailService,
+                                   UserService userService,
+                                   RedisTemplate<String, Object> redisTemplate) {
         this.jwtTokenUtil = jwtTokenUtil;
         this.userDetailService = userDetailService;
         this.userService = userService;
+        this.redisTemplate = redisTemplate;
     }
 
     // 原登录jwtTokenUtil.parseToken(token)获得的是学号,门户是手机号
@@ -60,7 +74,7 @@ public class JWTAuthenticationFilter extends OncePerRequestFilter {
             String phone = jwtTokenUtil.parseToken(token);
             Map<String, Object> userInfoMap = jwtTokenUtil.parseClaim(token).getBody().get("user_info", Map.class);
             // 不为空则认为是门户请求,此时同步用户信息
-            if(userInfoMap != null){
+            if (userInfoMap != null && shouldSyncUserInfo(userInfoMap, phone)) {
                 syncUserInfo(userInfoMap, phone);
             }
 
@@ -109,4 +123,28 @@ public class JWTAuthenticationFilter extends OncePerRequestFilter {
             userService.updateUserByPid(pid, update);
         }
     }
+
+    private boolean shouldSyncUserInfo(Map<String, Object> userInfoMap, String phone) {
+        if (!portalSyncEnabled || portalSyncThrottleSeconds <= 0) {
+            return true;
+        }
+
+        Object pid = userInfoMap.get("id");
+        String syncTarget = pid == null ? phone : pid.toString();
+        String throttleKey = "auth:portal-sync:" + syncTarget;
+
+        try {
+            Boolean shouldSync = redisTemplate.opsForValue().setIfAbsent(
+                    throttleKey,
+                    System.currentTimeMillis(),
+                    portalSyncThrottleSeconds,
+                    TimeUnit.SECONDS
+            );
+            return Boolean.TRUE.equals(shouldSync);
+        } catch (Exception e) {
+            // Redis is an optimization here; if unavailable we keep current auth behavior.
+            log.warn("shouldSyncUserInfo redis throttle failed, fallback to immediate sync. key={}", throttleKey, e);
+            return true;
+        }
+    }
 }

+ 13 - 0
src/main/resources/application-dev.yaml

@@ -7,6 +7,16 @@ spring:
     username: root
     password: eai123456
     url: jdbc:mysql://139.196.252.184:3306/eai?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&allowPublicKeyRetrieval=true
+    hikari:
+      maximum-pool-size: 30
+      minimum-idle: 10
+      connection-timeout: 10000
+      validation-timeout: 3000
+      idle-timeout: 600000
+      # Keep maxLifetime shorter than MySQL wait_timeout to avoid stale pooled connections.
+      max-lifetime: 240000
+      keepalive-time: 120000
+      leak-detection-threshold: 30000
   data:
     mongodb:
       uri: mongodb://admin:eai123456@139.196.252.184:27017/eai?authSource=admin
@@ -32,6 +42,9 @@ jwt:
   secret: UenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRW
   issuer: eai
   expiration: 86400
+  portal-sync:
+    enabled: true
+    throttle-seconds: 60
 
 
 aliyun:

+ 13 - 0
src/main/resources/application-prod.yaml

@@ -7,6 +7,16 @@ spring:
     username: root
     password: eai123456
     url: jdbc:mysql://139.196.252.184:3306/eai?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&allowPublicKeyRetrieval=true
+    hikari:
+      maximum-pool-size: 30
+      minimum-idle: 10
+      connection-timeout: 10000
+      validation-timeout: 3000
+      idle-timeout: 600000
+      # Keep maxLifetime shorter than MySQL wait_timeout to avoid stale pooled connections.
+      max-lifetime: 240000
+      keepalive-time: 120000
+      leak-detection-threshold: 30000
   data:
     mongodb:
       uri: mongodb://admin:eai123456@139.196.252.184:27017/eai?authSource=admin
@@ -34,6 +44,9 @@ jwt:
   secret: UenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRWUenM4KGb6DskRW
   issuer: eai
   expiration: 86400
+  portal-sync:
+    enabled: true
+    throttle-seconds: 60
 
 
 aliyun: