Sfoglia il codice sorgente

compareFaceSync api limit

deason 3 anni fa
parent
commit
b80f87729b

+ 42 - 1
examcloud-core-oe-task-api-provider/src/main/java/cn/com/qmth/examcloud/core/oe/task/controller/ExamCaptureController.java

@@ -26,9 +26,14 @@ import io.swagger.annotations.ApiOperation;
 import org.apache.commons.lang3.StringUtils;
 import org.json.JSONArray;
 import org.json.JSONException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.concurrent.TimeUnit;
+
 /**
  * @author chenken
  * @date 2018年9月6日 上午10:14:23
@@ -40,6 +45,8 @@ import org.springframework.web.bind.annotation.*;
 @RequestMapping("${app.api.oe.student.face}/examCaptureQueue")
 public class ExamCaptureController extends ControllerSupport {
 
+    private static final Logger log = LoggerFactory.getLogger(ExamCaptureController.class);
+
     @Autowired
     private ExamCaptureService examCaptureService;
 
@@ -52,6 +59,9 @@ public class ExamCaptureController extends ControllerSupport {
     @Autowired
     private RedisClient redisClient;
 
+    @Autowired
+    private RedisTemplate<String, Object> redisTemplate;
+
     @Autowired
     private ExamRecordDataService examRecordDataService;
 
@@ -72,9 +82,20 @@ public class ExamCaptureController extends ControllerSupport {
         if (StringUtils.isBlank(baseFaceToken)) {
             throw new StatusException("301002", "学生底照的faceToken为空");
         }
-        //		fileUrl = aes.decrypt(fileUrl);
+        //fileUrl = aes.decrypt(fileUrl);
         fileUrl = UrlUtil.decode(fileUrl);
+
+        if (this.isFaceApiLimitSeconds(user.getKey())) {
+            log.error("compareFaceSync outOfLimitSeconds...");
+            throw new StatusException("500503", "人脸验证太频繁,请稍后重试!");
+        }
+        if (this.isFaceApiLimitMinutes(user.getKey())) {
+            log.error("compareFaceSync outOfLimitMinutes...");
+            throw new StatusException("500503", "人脸验证太频繁,请10分钟后重试!");
+        }
+
         CompareFaceSyncInfo compareFaceSyncInfo = examCaptureService.compareFaceSyncByFileUrl(user.getUserId(), baseFaceToken, fileUrl);
+        log.warn("compareFaceSyncResult isPass = {}, fileUrl = {}, errorMsg = {}", fileUrl, compareFaceSyncInfo.getIsPass(), compareFaceSyncInfo.getErrorMsg());
 
         //将人脸同步比较的结果临时存储到redis中.开考后会清除
         String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
@@ -86,6 +107,26 @@ public class ExamCaptureController extends ControllerSupport {
         return compareFaceSyncInfo;
     }
 
+    private boolean isFaceApiLimitSeconds(String userKey) {
+        String cacheKey = "$FACE_API_LIMIT:S_" + userKey;
+
+        Long count = redisTemplate.opsForValue().increment(cacheKey);
+        redisTemplate.expire(cacheKey, 2, TimeUnit.SECONDS);
+
+        // 限制请求:1次/2秒
+        return count > 1;
+    }
+
+    private boolean isFaceApiLimitMinutes(String userKey) {
+        String cacheKey = "$FACE_API_LIMIT:M_" + userKey;
+
+        Long count = redisTemplate.opsForValue().increment(cacheKey);
+        redisTemplate.expire(cacheKey, 10, TimeUnit.MINUTES);
+
+        // 限制请求:50次/10分钟
+        return count > 50;
+    }
+
     /**
      * 校验又拍云签名
      *