ソースを参照

手机号获取兼容老版本

chunping 3 年 前
コミット
d205dc91b7

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

@@ -1,6 +1,7 @@
 package com.qs.mp.web.controller.api.common;
 
 import cn.jsms.api.ValidSMSResult;
+import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -35,6 +36,9 @@ import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
 import org.apache.commons.io.FileUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -44,6 +48,7 @@ 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 sun.misc.BASE64Decoder;
 
 /**
  * @auther duota
@@ -97,6 +102,10 @@ public class UserController extends BaseApiController {
   @Autowired
   private SysLoginService sysLoginService;
 
+  private static final String ECB_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
+  private static final String KEY_ALGORITHM = "AES";
+  private static final String UTF8 = "UTF-8";
+
 
   @RequestMapping(value = "/user/wxauth", method = RequestMethod.POST)
   @ResponseBody
@@ -169,23 +178,49 @@ public class UserController extends BaseApiController {
   public AjaxResult wxauthMobile(@RequestBody WxLoginParams wxLoginParams) {
     String appId = userAppId;
     String appSecret = userAppSecret;
-    if (UserIdentityEnum.isChannel(wxLoginParams.getIdentity())) {
+    /*if (UserIdentityEnum.isChannel(wxLoginParams.getIdentity())) {
       appId = channelAppId;
       appSecret = channelAppSecret;
+    }*/
+    JSONObject phoneInfo;
+    if (StringUtils.isNotBlank(wxLoginParams.getCode())) {
+      //调用微信后台接口获取openId
+      String res = getWxMobile(wxLoginParams, appId);
+      JSONObject jsonObject = JSONObject.parseObject(res);
+      int errcode = jsonObject.getIntValue("errcode");
+      if (errcode != 0) {
+        LogUtil.error(logger, "手机号获取失败:" + res);
+        return error("手机号获取失败");
+      }
+      phoneInfo = jsonObject.getJSONObject("phone_info");
+    } else {
+      String res = weixinDecrypt(wxLoginParams.getEncryptedData(), appSecret, wxLoginParams.getIv());
+      if (StringUtils.isBlank(res)) {
+        return error("手机号获取失败");
+      }
+      /**
+       * {
+       *     "phoneNumber": "13580006666",
+       *     "purePhoneNumber": "13580006666",
+       *     "countryCode": "86",
+       *     "watermark":
+       *     {
+       *         "appid":"APPID",
+       *         "timestamp": TIMESTAMP
+       *     }
+       * }
+       */
+      phoneInfo = JSON.parseObject(res);
+      JSONObject watermark = phoneInfo.getJSONObject("watermark");
+      if (!appId.equals(watermark.getString("appid"))) {
+        LogUtil.error(logger, "手机号解密appid不符,appid:{0}",  watermark.getString("appid"));
+        return error("手机号获取失败");
+      }
     }
-    //调用微信后台接口获取openId
-    String res = getWxMobile(wxLoginParams, appId);
-    JSONObject jsonObject = JSONObject.parseObject(res);
-    int errcode = jsonObject.getIntValue("errcode");
-    if (errcode != 0 ) {
-      LogUtil.error(logger, "手机号获取失败:" + res);
-      return error("手机号获取失败");
-    }
-    JSONObject phoneInfo = jsonObject.getJSONObject("phone_info");
     String phoneNumber = phoneInfo.getString("phoneNumber");
 
     if (StringUtils.isBlank(phoneNumber)) {
-      LogUtil.error(logger, "微信手机号不存在:" + res);
+      LogUtil.error(logger, "微信手机号不存在:" + phoneInfo);
       return error("手机号获取失败");
     }
     AjaxResult ajax = AjaxResult.success();
@@ -349,4 +384,39 @@ public class UserController extends BaseApiController {
     return result;
   }
 
+  /**
+   * 带有初始变量的解密(微信用)
+   *
+   * @param content     密文
+   * @param skey        密钥
+   * @param ivParameter 初始向量
+   * @return
+   * @throws Exception
+   */
+  public String weixinDecrypt(String content, String skey, String ivParameter) {
+    try {
+      BASE64Decoder decoder = new BASE64Decoder();
+      // 根据微信文档要求需要把 密文、密钥、iv 使用BASE64进行解码
+      byte[] keyByte = new BASE64Decoder().decodeBuffer(skey);
+      byte[] contentByte = decoder.decodeBuffer(content);
+      byte[] ivByte = decoder.decodeBuffer(ivParameter);
+      // 生成密码
+      SecretKeySpec keySpec = new SecretKeySpec(keyByte, KEY_ALGORITHM);
+      // 生成IvParameterSpec
+      IvParameterSpec iv = new IvParameterSpec(ivByte);
+      // 初始化解密 指定模式 AES/CBC/PKCS5Padding
+      Cipher cipher = Cipher.getInstance(ECB_CIPHER_ALGORITHM);
+      // 指定解密模式 传入密码 iv
+      cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
+      // 解密
+      byte[] result = cipher.doFinal(contentByte);
+      return new String(result, UTF8);
+    } catch (Exception e) {
+      LogUtil.error(logger, e, "【解密错误】content:{0},ivParameter:{1}", new Object[]{content, ivParameter});
+      return null;
+    }
+  }
+
+
+
 }

+ 4 - 1
mp-service/src/main/java/com/qs/mp/system/domain/vo/WxLoginParams.java

@@ -12,9 +12,12 @@ public class WxLoginParams {
     private String code;   //微信返回code,用于服务端换取鉴权信息
     private String nickName;
     private String avatarUrl;
+    /** 微信手机号授权信息 */
+    private String encryptedData; // 包括敏感数据在内的完整用户信息的加密数据
+    private String iv; // 加密算法的初始向量
     /**
      * 登录身份
      */
-    private int identity = 2;
+    private int identity;
 
 }