zoujiajian 2 lat temu
rodzic
commit
7c17f41567

+ 5 - 0
netflix-common/pom.xml

@@ -98,6 +98,11 @@
             <artifactId>tencentcloud-sdk-java-sms</artifactId>
             <version>3.1.694</version>
         </dependency>
+        <dependency>
+            <groupId>com.tencentcloudapi</groupId>
+            <artifactId>tencentcloud-sdk-java</artifactId>
+            <version>4.0.11</version>
+        </dependency>
     </dependencies>
 
 

+ 52 - 0
netflix-common/src/main/java/com/cyksj/common/util/SmsUtil.java

@@ -4,6 +4,10 @@ import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpResponse;
 import cn.hutool.http.Method;
 import cn.hutool.json.JSONObject;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.tencentcloudapi.captcha.v20190722.CaptchaClient;
+import com.tencentcloudapi.captcha.v20190722.models.DescribeCaptchaResultRequest;
+import com.tencentcloudapi.captcha.v20190722.models.DescribeCaptchaResultResponse;
 import com.tencentcloudapi.common.Credential;
 import com.tencentcloudapi.common.exception.TencentCloudSDKException;
 import com.tencentcloudapi.common.profile.ClientProfile;
@@ -47,6 +51,16 @@ public class SmsUtil {
 
     private static final Logger log = LoggerFactory.getLogger(SmsUtil.class);
 
+    private static final String TENCENT_CAPTCHA_SECRET_ID = "AKIDogNE1uQ3azlVH0582pS0gRD7HZ3aIAYs";
+
+    private static final String TENCENT_CAPTCHA_SECRET_KEY = "Ig2SnIyeHqK5tmrw27kR4bJ727bAsjSX";
+
+    //腾讯云图形认证密钥id
+    private static final Long TENCENT_CAPTCHA_APP_ID = 197694921l;
+
+    //腾讯云图形认证密钥key
+    private static final String TENCENT_CAPTCHA_APP_SECRET_KEY = "vOd32NejzMM2HQX0WtKy7ItvK";
+
     public static void main(String[] args) {
         send("15720916464", "尊敬的用户,您的验证码为123456,此验证码仅用于银河录像。【银河录像局】");
     }
@@ -182,4 +196,42 @@ public class SmsUtil {
         }
         return false;
     }
+
+    public static void checkTencentCaptcha(String ticket, String userIp,String randsStr) {
+        try {
+            // 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
+            // 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
+            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
+            Credential cred = new Credential(TENCENT_CAPTCHA_SECRET_ID, TENCENT_CAPTCHA_SECRET_KEY);
+            // 实例化一个http选项,可选的,没有特殊需求可以跳过
+            HttpProfile httpProfile = new HttpProfile();
+            // 推荐使用北极星,相关指引可访问如下链接
+            // https://git.woa.com/tencentcloud-internal/tencentcloud-sdk-java#%E5%8C%97%E6%9E%81%E6%98%9F
+            httpProfile.setEndpoint("captcha.tencentcloudapi.com");
+            // 实例化一个client选项,可选的,没有特殊需求可以跳过
+            ClientProfile clientProfile = new ClientProfile();
+            clientProfile.setHttpProfile(httpProfile);
+            // 实例化要请求产品的client对象,clientProfile是可选的
+            CaptchaClient client = new CaptchaClient(cred, "", clientProfile);
+            // 实例化一个请求对象,每个接口都会对应一个request对象
+            DescribeCaptchaResultRequest req = new DescribeCaptchaResultRequest();
+            req.setCaptchaType(9L);
+            req.setTicket(ticket);
+            req.setUserIp(userIp);
+            req.setRandstr(randsStr);
+            req.setCaptchaAppId(TENCENT_CAPTCHA_APP_ID);
+            req.setAppSecretKey(TENCENT_CAPTCHA_APP_SECRET_KEY);
+
+            // 返回的resp是一个DescribeCaptchaResultResponse的实例,与请求对象对应
+            DescribeCaptchaResultResponse resp = client.DescribeCaptchaResult(req);
+            //1 OK 验证通过
+            Long captchaCode = resp.getCaptchaCode();
+            if (captchaCode != 1) {
+                log.error("腾讯云图形验证错误:{}", resp.getCaptchaMsg());
+                throw BusinessRuntimeException.getInstance("");
+            }
+        } catch (TencentCloudSDKException e) {
+            log.error("腾讯云图形认证异常:{}", StringUtil.getErrorText(e));
+        }
+    }
 }

+ 4 - 2
netflix-service/src/main/java/com/cyksj/service/stripe/StripeService.java

@@ -11,7 +11,10 @@ import com.cyksj.model.request.OrderRefundReq;
 import com.cyksj.service.order.OrderDonService;
 import com.stripe.Stripe;
 import com.stripe.exception.StripeException;
-import com.stripe.model.*;
+import com.stripe.model.BalanceTransaction;
+import com.stripe.model.Charge;
+import com.stripe.model.PaymentIntent;
+import com.stripe.model.Refund;
 import com.stripe.model.checkout.Session;
 import com.stripe.param.RefundCreateParams;
 import com.stripe.param.checkout.SessionCreateParams;
@@ -20,7 +23,6 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
-import java.math.RoundingMode;
 import java.util.Date;
 import java.util.HashMap;
 

+ 3 - 1
netflix-service/src/main/java/com/cyksj/service/user/BadIntentionOpService.java

@@ -1,5 +1,7 @@
 package com.cyksj.service.user;
 
+import javax.servlet.http.HttpServletRequest;
+
 public interface BadIntentionOpService {
-    void checkHandleBadUserOp(String phone);
+    void checkHandleBadUserOp(String phone, String verifyCode, String ticket, String randStr, HttpServletRequest request);
 }

+ 19 - 4
netflix-service/src/main/java/com/cyksj/service/user/impl/BadIntentionOpServiceImpl.java

@@ -1,12 +1,18 @@
 package com.cyksj.service.user.impl;
 
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.extra.servlet.ServletUtil;
 import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.common.i18n.I18nMessageUtil;
+import com.cyksj.common.util.SmsUtil;
 import com.cyksj.redis.RedisService;
 import com.cyksj.service.user.BadIntentionOpService;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
+import javax.servlet.http.HttpServletRequest;
+
 @Service
 @RequiredArgsConstructor
 @Slf4j
@@ -17,13 +23,21 @@ public class BadIntentionOpServiceImpl implements BadIntentionOpService {
     private static final int PHONE_CODE_GET_NUM_DAY_MAX_BLACK = 50;
 
     @Override
-    public void checkHandleBadUserOp(String phone) {
+    public void checkHandleBadUserOp(String phone, String verifyCode, String ticket, String randStr, HttpServletRequest request) {
         if ("13662979985".equals(phone)) {
-            throw BusinessRuntimeException.getInstance("异常手机号");
+            throw BusinessRuntimeException.getInstance(I18nMessageUtil.getI18nMsg("sys_error"));
+        }
+
+        if (ObjectUtil.hasEmpty(ticket, randStr)) {
+            throw BusinessRuntimeException.getInstance(I18nMessageUtil.getI18nMsg("sys_error"));
+        } else {
+            //腾讯云图形验证
+            String ip = ServletUtil.getClientIP(request);
+            SmsUtil.checkTencentCaptcha(ticket, ip, randStr);
         }
         String dayKey = RedisService.key.PHONE_CODE_USER_NUM_KEY_DAY.getName() + phone;
         if (redisService.hasKey(RedisService.key.PHONE_CODE_BALCK_KEY.getName() + phone)) {
-            throw BusinessRuntimeException.getInstance("异常手机号");
+            throw BusinessRuntimeException.getInstance(I18nMessageUtil.getI18nMsg("sys_error"));
         }
         if (redisService.hasKey(dayKey)) {
             Long incr = redisService.incr(dayKey, 1l);
@@ -34,10 +48,11 @@ public class BadIntentionOpServiceImpl implements BadIntentionOpService {
 
             if (incr.intValue() > PHONE_CODE_GET_NUM_DAY_LIMIT) {
                 log.error("手机号:{}频繁获取短信验证码", phone);
-                throw BusinessRuntimeException.getInstance("请勿频繁获取短信验证码");
+                throw BusinessRuntimeException.getInstance(I18nMessageUtil.getI18nMsg("sys_error"));
             }
             return;
         }
         redisService.set(dayKey, 1, RedisService.key.PHONE_CODE_USER_NUM_KEY_DAY.getTimeout());
+
     }
 }

+ 5 - 5
netflix-web/src/main/java/com/cyksj/web/controller/user/AuthorizationController.java

@@ -3,7 +3,6 @@ package com.cyksj.web.controller.user;
 import cn.hutool.core.lang.Validator;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.cyksj.common.EnvCommonService;
 import com.cyksj.common.annotation.NoSubmit;
 import com.cyksj.common.exception.BusinessRuntimeException;
 import com.cyksj.common.i18n.I18nMessageUtil;
@@ -34,6 +33,7 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.dao.DuplicateKeyException;
 import org.springframework.web.bind.annotation.*;
 
+import javax.servlet.http.HttpServletRequest;
 import java.util.Collections;
 
 /**
@@ -53,12 +53,12 @@ public class AuthorizationController {
 
     private final BadIntentionOpService badIntentionOpService;
 
-    private final EnvCommonService envCommonService;
-
     private final PhoneCodeMapper phoneCodeMapper;
 
     private final MailService mailService;
 
+    private final HttpServletRequest request;
+
     @Value("${google.clientId}")
     private String clientId;
 
@@ -67,7 +67,7 @@ public class AuthorizationController {
      */
     @GetMapping("/get/phone/code")
     @NoSubmit
-    public Result<String> getPhoneCode(String phone, Integer digit, @RequestParam(defaultValue = "0") Boolean isFree, Integer cid) throws Exception {
+    public Result<String> getPhoneCode(String phone, Integer digit, @RequestParam(defaultValue = "0") Boolean isFree, Integer cid, String verifyCode, String ticket,String randStr) throws Exception {
         if (cid == null) cid = 86;
         if (StrUtil.isBlank(phone) || (86 == cid && !Validator.isMobile(phone))) {
             throw BusinessRuntimeException.getInstance(I18nMessageUtil.getI18nMsg("phone_format_error"));
@@ -81,7 +81,7 @@ public class AuthorizationController {
             throw BusinessRuntimeException.getInstance(I18nMessageUtil.getI18nMsg("verify_code_validity"));
         }
         //是否是恶意用户
-        badIntentionOpService.checkHandleBadUserOp(phone);
+        badIntentionOpService.checkHandleBadUserOp(phone, verifyCode, ticket, randStr, request);
         String code = StringUtil.getRandomCodeStr(digit);
         Boolean isFlag;
         if (!isFree) {