소스 검색

支付宝授权获取用户手机号

cup 2 년 전
부모
커밋
efbaf5f529

+ 6 - 0
mp-admin/pom.xml

@@ -17,6 +17,12 @@
 
     <dependencies>
 
+        <dependency>
+            <groupId>com.alipay.sdk</groupId>
+            <artifactId>alipay-sdk-java</artifactId>
+            <version>4.31.12.ALL</version>
+        </dependency>
+
         <!--快递100SDK-->
         <dependency>
             <groupId>com.github.kuaidi100-api</groupId>

+ 126 - 8
mp-admin/src/main/java/com/qs/mp/web/controller/api/common/UserController.java

@@ -1,14 +1,25 @@
 package com.qs.mp.web.controller.api.common;
 
+import cn.hutool.json.JSONUtil;
 import cn.jsms.api.ValidSMSResult;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.TypeReference;
+import com.alibaba.fastjson.parser.Feature;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.AlipayClient;
+import com.alipay.api.DefaultAlipayClient;
+import com.alipay.api.internal.util.AlipayEncrypt;
+import com.alipay.api.internal.util.AlipaySignature;
+import com.alipay.api.request.AlipaySystemOauthTokenRequest;
+import com.alipay.api.response.AlipaySystemOauthTokenResponse;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.qs.mp.channel.domain.Channel;
 import com.qs.mp.channel.service.IChannelService;
 import com.qs.mp.common.constant.Constants;
 import com.qs.mp.common.core.domain.AjaxResult;
+import com.qs.mp.common.domain.vo.AliPhoneDecryptVO;
 import com.qs.mp.common.enums.UserIdentityEnum;
 import com.qs.mp.common.enums.WxActTypeEnum;
 import com.qs.mp.common.jsms.JSMSUtils;
@@ -40,15 +51,13 @@ import java.util.Map;
 import javax.crypto.Cipher;
 import javax.crypto.spec.IvParameterSpec;
 import javax.crypto.spec.SecretKeySpec;
+
+import io.swagger.annotations.ApiOperation;
 import org.apache.commons.io.FileUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
-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.ResponseBody;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 import sun.misc.BASE64Decoder;
 import sun.misc.BASE64Encoder;
 
@@ -86,6 +95,19 @@ public class UserController extends BaseApiController {
   @Value("${wx-user.appSecret}")
   private String userAppSecret;
 
+  @Value("${ali-miniApp.appId}")
+  private String aliAppId;
+  @Value("${ali-miniApp.public-key}")
+  private String aliPublicKey;
+  @Value("${ali-miniApp.private-key}")
+  private String aliPrivateKey;
+
+  @Value("{ali-miniApp.serverUrl}")
+  private String serverUrl;
+
+  @Value("{ali-miniApp.decrypt-key}")
+  private String decryptKey;
+
   /**
    * 文件上传路径
    */
@@ -109,6 +131,90 @@ public class UserController extends BaseApiController {
   private static final String UTF8 = "UTF-8";
 
 
+  @ApiOperation("支付宝获取用户手机号")
+  @PostMapping("/user/aliAuth/mobile")
+  public AjaxResult aliAuthMobile(@RequestBody WxLoginParams wxLoginParams) {
+
+    String response = wxLoginParams.getEncryptedData();
+
+    //1. 获取验签和解密所需要的参数
+    Map<String, String> openapiResult = JSON.parseObject(response,
+            new TypeReference<Map<String, String>>() {
+            }, Feature.OrderedField);
+    String signType = "RSA2";
+    String charset = "UTF-8";
+    String encryptType = "AES";
+    String sign = openapiResult.get("sign");
+    String content = openapiResult.get("response");
+
+    // 是否加密
+    boolean isDataEncrypted = !content.startsWith("{");
+    boolean signCheckPass = false;
+
+    //2. 验签
+    String signContent = content;
+    String signVeriKey = aliPublicKey;
+    // 如果是加密的报文则需要在密文的前后添加双引号
+    if (isDataEncrypted) {
+      signContent = "\"" + signContent + "\"";
+    }
+    try {
+      signCheckPass = AlipaySignature.rsaCheck(signContent, sign, signVeriKey, charset, signType);
+    } catch (AlipayApiException e) {
+      // 验签异常, 日志
+    }
+    if(!signCheckPass) {
+      // 验签不通过(异常或者报文被篡改),终止流程(不需要做解密)
+      LogUtil.warn(logger, "验签失败");
+      AjaxResult.error("验签失败");
+    }
+
+    //3. 解密
+    String plainData = null;
+    if (isDataEncrypted) {
+      try {
+        plainData = AlipayEncrypt.decryptContent(content, encryptType, decryptKey, charset);
+      } catch (AlipayApiException e) {
+        //解密异常, 记录日志
+        LogUtil.warn(logger, "解密异常");
+        AjaxResult.error("解密异常");
+      }
+    } else {
+      plainData = content;
+    }
+
+    // 转对象 异常情况处理
+
+    AliPhoneDecryptVO aliPhoneDecryptVO = JSONUtil.toBean(plainData, AliPhoneDecryptVO.class);
+    if (!aliPhoneDecryptVO.isSuccess()) {
+      LogUtil.error(logger,"解析手机号失败,errorMsg:{0}", plainData);
+      return AjaxResult.error("解析手机号失败," + aliPhoneDecryptVO.getSubMsg());
+    }
+    String mobile = aliPhoneDecryptVO.getMobile();
+
+    AjaxResult ajax = AjaxResult.success();
+    SysUser sysUser = sysUserService.selectUserByUserName(mobile);
+    if (null == sysUser) {
+      if (wxLoginParams.getIdentity() != UserIdentityEnum.USER.ordinal()) {
+        return error("用户不存在,请联系客服");
+      }
+      // C端直接注册新用户
+      sysUser = new SysUser();
+      sysUser.setUserName(mobile);
+      sysUser.setNickName(mobile);
+      sysUser.setPhonenumber(mobile);
+      sysUserService.registerUser(sysUser);
+    }
+    Map<String, String> result = sysLoginService.wxAuthLogin(mobile, wxLoginParams.getIdentity());
+    for (String key : result.keySet()) {
+      ajax.put(key, result.get(key));
+    }
+    return ajax;
+  }
+
+
+
+  @ApiOperation("微信授权登录")
   @RequestMapping(value = "/user/wxauth", method = RequestMethod.POST)
   @ResponseBody
   public AjaxResult wxauth(@RequestBody WxLoginParams wxLoginParams) {
@@ -177,6 +283,7 @@ public class UserController extends BaseApiController {
   }
 
 
+  @ApiOperation("微信授权获取用户手机号")
   @RequestMapping(value = "/user/wxauth/mobile", method = RequestMethod.POST)
   @ResponseBody
   public AjaxResult wxauthMobile(@RequestBody WxLoginParams wxLoginParams) {
@@ -283,6 +390,7 @@ public class UserController extends BaseApiController {
   /**
    * 查询当前登录用户信息
    */
+  @ApiOperation("查询当前登录用户信息")
   @RequestMapping(value = "/user/getLoginUserinfo", method = RequestMethod.POST)
   public AjaxResult getLoginUserinfo(@RequestBody JSONObject params) {
     LoginUser loginUser = SecurityUtils.getLoginUser();
@@ -434,9 +542,19 @@ public class UserController extends BaseApiController {
     }
   }
 
-  public static void main(String[] args) {
-    UserController userController = new UserController();
-    System.out.println(userController.weixinDecrypt("qvNE+SHdiP2GTbmNaqahrhhLw7EZetcMhUMV9yPXHxBbWOMcZ5gFxOGliXC9uojyC0NDUXCUi1xvFVDKMYREQ7rLXXrZIkB1jEleJNuUb9kO3LCDRucvbGAbVwm2EsTNsd5VbqI3fKdu0IOxmmSAWCLZNGXZBlki4ke62lI+ASg6dPohQmmCux8jwD2Js3ZnDQN2mb0JPRT68Qj716gYvA==", "QJ/WdeFANTIfIErOCJ2jNg==", "60YJmIckq4kaXp88wAGGHA=="));
+  public static void main(String[] args) throws AlipayApiException {
+//    UserController userController = new UserController();
+//    System.out.println(userController.weixinDecrypt("qvNE+SHdiP2GTbmNaqahrhhLw7EZetcMhUMV9yPXHxBbWOMcZ5gFxOGliXC9uojyC0NDUXCUi1xvFVDKMYREQ7rLXXrZIkB1jEleJNuUb9kO3LCDRucvbGAbVwm2EsTNsd5VbqI3fKdu0IOxmmSAWCLZNGXZBlki4ke62lI+ASg6dPohQmmCux8jwD2Js3ZnDQN2mb0JPRT68Qj716gYvA==", "QJ/WdeFANTIfIErOCJ2jNg==", "60YJmIckq4kaXp88wAGGHA=="));
+
+    String charset = "UTF-8";
+    String encryptType = "AES";
+
+    String publicKey1 = "al2021003127607930AES";
+    String s = AlipayEncrypt.encryptContent("17681682549", encryptType, publicKey1, charset);
+    System.out.println("s = " + s);
+    String s2 = AlipayEncrypt.decryptContent(s, encryptType, publicKey1, charset);
+    System.out.println("s2 = " + s2);
+
   }
 
 }

+ 8 - 0
mp-admin/src/main/resources/application.yml

@@ -138,6 +138,14 @@ wx-user:
 wxgzh:
   appId: wxfe9785e665c741a2
 
+# 支付宝盲票小程序appId和公钥私钥
+ali-miniApp:
+  appId: 2021003127607930
+  serverUrl: "https://openapi.alipay.com/gateway.do"
+  public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgti2dfmICYSuMNNHFta63S4e6+FaDo0Euyj5e5pjN77LERJ4PENi3a++fIfnBUe4YNPqFMoERc7Ea8hM6PPlRUQNSyKiUTt598vNm4z7jHAHjYU4N8bx7KrkBJIRaJlmHZI+tY+c2M5Y1FyQXQew5LT9D1OVzHAZRbWe8yTGlNL96qNPkVxQhv1LWDwc8NWncn+9Eyimp9qPtmVMvVQGwwqF/VVueBX60pjV0jjCOaY9onXMtoADZHKF0VlzND5gE2DFcq4Ut1VlhovxudRt94mrnat4IT6Mrr+Iy8qGose7I3Qp+Dmlwed8y5u//akoY4jiVKHJ9/XbqoqUqyM27wIDAQAB
+  private-key: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCC2LZ1+YgJhK4w00cW1rrdLh7r4VoOjQS7KPl7mmM3vssREng8Q2Ldr758h+cFR7hg0+oUygRFzsRryEzo8+VFRA1LIqJRO3n3y82bjPuMcAeNhTg3xvHsquQEkhFomWYdkj61j5zYzljUXJBdB7DktP0PU5XMcBlFtZ7zJMaU0v3qo0+RXFCG/UtYPBzw1adyf70TKKan2o+2ZUy9VAbDCoX9VW54FfrSmNXSOMI5pj2idcy2gANkcoXRWXM0PmATYMVyrhS3VWWGi/G51G33iaudq3ghPoyuv4jLyoaix7sjdCn4OaXB53zLm7/9qShjiOJUocn39duqipSrIzbvAgMBAAECggEAGACVB/MsR0K1iXNYWRIu2R/6wB5onL61nXeYvFnH1ZQEQC95KuTZn/z7HnD3qfpMEkcNa57bRcr2MSdfJGSJLDmdjqjdybT1XMVgBCbKhiqO2CEV/PVbr6Rxi30YAG4TU11eb4PWq9a+aMZKHSaqBmpE+ajFk+kEWctFSyj13JrKCThHqzj9PPi0OdB/SrbhHgRf9yL4XeE6bBxQ+iWDFTtoAeI5quOsH7h8yOSfp84e40kaFW3cJOzOJboFl308yhlV7/9ap3CWz7R2o0I8fSls5s4GiX62FSXuP0jocnhj1jlOmFW8UAg65pSE8B9X691JUuLQQt/WNolLdGI3EQKBgQDxX52UZHiyIbQhZzRa2dChMaN+p7r8lVxqW3d0dTYmnUbdpeP0z9ivhVC2S7DhONd3GtwmH+e86VoS+1IZlzxoXgrDptFv2IvuxtlZ2RsXS+Y66yTDJCGbrVDtjeWGlJqiRaTPlufdxq3qawIzhpxluBpCrCP79D9VTvzmVYbaPQKBgQCKxoMM6dc3NE9mG7BM3D5lFD0BZo2osPk4cu7t0llNlZdsmtslphTbIu+HMwbzmvDJ/fRABgzkVwubSKxwHEmNl3qMGH5smAVWi6t5QzZ4HYWrYSmJhBegeTvEvWFSb1hyHnpJRGUPXWFJfbM9aC4xCJcZoNKS/k1Zt4M/OkakmwKBgDhV2LGJwaHRu/kP3WhW7hqxOzeUblAFjExGjNrhgIICs0eIMGwzFp/gvbXOdLocSi3CVx+O0seEr0E+5yqR4cd6K4j+pmM0Z3STdKdDxM7rKBEYULw68p0jFoBbXfbLOEwndQ/+aJ+af3z2/MyJ3nbfQUHOa5eiqiV/Cge4boEBAoGANVPTSEMT0MLpP/Oj6+U2lOESEFe4V/qpymdgKUOLzaSOa82WKQGJQixKn0mcgkAoB3bvRSsOCTDp5OIoYWx9V0u+a9d9vX0tj/RcEF0jsUSm+RR9Qbrg2Wm87f1YSLVA55mOpFkD/MOFfxguqIpANdd3OQHz6UiPsMo0RTe/rcECgYEAhMX5DsSXM4WyAHyYTQW3NVH1ehFcf6yp4uCSj+hq3SMezKYS/dRNSA912XM3rJakrjaVNzRTnSuwfajIYi68A1TjS/rj6OTAx7V5HEeYS2U1VLR5Ai7VKHc85Kye4LuF5hIp35/vYo3qHZLZFsM7eDP9SGVG/zUje6Ce1QTFrp8=
+  decrypt-key: fhixMEfC0kpw9drqNJiMfQ==
+
 #三方支付配置
 pay:
   notifyUrl: https://www.quanshu123.com

+ 170 - 0
mp-admin/src/test/java/com/qs/mp/task/MyTest.java

@@ -0,0 +1,170 @@
+package com.qs.mp.task;
+
+import cn.hutool.core.codec.Base62;
+import cn.hutool.core.date.LocalDateTimeUtil;
+import cn.hutool.core.util.HashUtil;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.symmetric.DES;
+import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
+import cn.hutool.crypto.symmetric.SymmetricCrypto;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.qs.mp.admin.domain.Marketing;
+import com.qs.mp.common.core.redis.DistributedLocker;
+import com.qs.mp.common.core.redis.RedisCache;
+import com.qs.mp.common.enums.UserTypeEnum;
+import com.qs.mp.common.utils.AESUtil;
+import com.qs.mp.common.utils.DateUtils;
+import com.qs.mp.common.utils.RSAUtil;
+import com.qs.mp.common.utils.WebhookService;
+import com.qs.mp.common.utils.html.EscapeUtil;
+import com.qs.mp.common.utils.uuid.IdUtils;
+import com.qs.mp.common.utils.uuid.UUID;
+import com.qs.mp.framework.service.IWxSubscribeMessage;
+import com.qs.mp.pay.service.IWalletService;
+import com.qs.mp.quartz.task.DayStatTask;
+import com.qs.mp.quartz.task.MarketingTask;
+import com.qs.mp.system.service.id.BizIdGenerator;
+import com.qs.mp.user.domain.MarketingUserCode;
+import com.qs.mp.user.service.IMarketingUserCodeService;
+import com.qs.mp.utils.SecurityUtils;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.util.*;
+
+/**
+ * @author Cup
+ * @date 2022/4/26
+ */
+@SpringBootTest
+public class MyTest {
+
+    @Autowired
+    private IWalletService walletService;
+
+    @Autowired
+    private MarketingTask marketingTask;
+
+    @Autowired
+    private RedisCache redisCache;
+
+    @Autowired
+    private BizIdGenerator bizIdGenerator;
+
+    @Autowired
+    private IWxSubscribeMessage wxSubscribeMessage;
+
+
+    @Autowired
+    private IMarketingUserCodeService marketingUserCodeService;
+
+
+    @Autowired
+    private DayStatTask dayStatTask;
+
+
+    public static void main(String[] args) {
+        WebhookService.sendAlertDing("mayday,mayday,上上下下,左右左右,BABA");
+
+        String decrypt = AESUtil.decrypt("75213771c6c781d62136e39180303be03f0a99761114c1264f116051a9e95108");
+        System.out.println("decrypt = " + decrypt);
+
+    }
+
+    @Test
+    void test9() {
+
+    }
+
+    @Test
+    void test8(){
+        dayStatTask.stat("20220617");
+    }
+
+
+    @Test
+    void test7() {
+        String hellow = AESUtil.encrypt("hellow");
+        System.out.println("hellow = " + hellow);
+        String decrypt = AESUtil.decrypt("hahaha");
+        System.out.println("decrypt = " + decrypt);
+    }
+
+
+    @Test
+    void test6(){
+//        List<MarketingUserCode> userCodeList = marketingUserCodeService.list(new LambdaQueryWrapper<MarketingUserCode>()
+//                .select(MarketingUserCode::getUserId)
+//                .eq(MarketingUserCode::getMarketingId, 102)
+////                .eq(MarketingUserCode::getUserType, UserTypeEnum.ORDINARY.getValue())
+//                .groupBy(MarketingUserCode::getUserId));
+        List<MarketingUserCode> userCodeList = marketingUserCodeService.list(new LambdaQueryWrapper<MarketingUserCode>()
+                .select(MarketingUserCode::getUserId)
+                .eq(MarketingUserCode::getUserType, UserTypeEnum.ORDINARY.getValue())
+                .groupBy(MarketingUserCode::getUserId));
+        userCodeList.forEach(System.out::println);
+    }
+
+    @Test
+    void test5() {
+        Set<String> testSet =new HashSet<>();
+        testSet.add("test1");
+        testSet.add("test2");
+        testSet.add("test3");
+        testSet.add("test4");
+        redisCache.setCacheSet("testSet",testSet);
+        List<Object> list = new ArrayList<>();
+        list.add("test1");
+        list.add("test3");
+        list.add("test5");
+        list.add("test6");
+        list.add("test7");
+        redisCache.removeSetValueByKey("testSet",list);
+
+
+    }
+
+    @Test
+    void test4() {
+        Marketing marketing = new Marketing();
+        marketing.setId(45L);
+        marketing.setTitle("测试订阅通");
+        wxSubscribeMessage.sendMarketingLottery(188L, marketing);
+        wxSubscribeMessage.sendMarketingLottery(79L, marketing);
+
+//        wxSubscribeMessage.sendMarketingStart(188L, marketing);
+//        wxSubscribeMessage.sendMarketingStart(79L, marketing);
+
+//        wxSubscribeMessage.sendMarketingHelp(188L, marketing);
+//        wxSubscribeMessage.sendMarketingHelp(79L, marketing);
+    }
+    
+    @Test
+    void test2() throws IOException {
+        marketingTask.lottery();
+
+    }
+
+    @Test
+    void test3(){
+        for (int i = 0; i < 20; i++) {
+            System.out.println("bizIdGenerator = " + bizIdGenerator.newId());
+        }
+
+    }
+
+
+
+    @Test
+    void test1(){
+        walletService.refund("968527112497659906",10,"测试");
+    }
+
+}

+ 22 - 0
mp-service/src/main/java/com/qs/mp/common/domain/vo/AliPhoneDecryptVO.java

@@ -0,0 +1,22 @@
+package com.qs.mp.common.domain.vo;
+
+import lombok.Data;
+import org.apache.commons.lang3.math.NumberUtils;
+
+/**
+ * 支付宝手机解密结果类
+ * @author Cup
+ * @date 2022/6/21
+ */
+@Data
+public class AliPhoneDecryptVO {
+    private String code;
+    private String msg;
+    private String mobile;
+    private String subCode;
+    private String subMsg;
+
+    public boolean isSuccess() {
+        return "10000".equals(code) && NumberUtils.isDigits(mobile);
+    }
+}