diff --git a/cash-api/account-server/pom.xml b/cash-api/account-server/pom.xml index 060a0610..007aa79f 100644 --- a/cash-api/account-server/pom.xml +++ b/cash-api/account-server/pom.xml @@ -36,6 +36,8 @@ + + diff --git a/cash-api/account-server/src/main/java/com/czg/controller/user/UserAuthorizationController.java b/cash-api/account-server/src/main/java/com/czg/controller/user/UserAuthorizationController.java index 0868e02c..bb25a8fe 100644 --- a/cash-api/account-server/src/main/java/com/czg/controller/user/UserAuthorizationController.java +++ b/cash-api/account-server/src/main/java/com/czg/controller/user/UserAuthorizationController.java @@ -1,5 +1,6 @@ package com.czg.controller.user; +import com.czg.account.dto.auth.GetPhoneDTO; import com.czg.account.dto.auth.LoginTokenDTO; import com.czg.account.dto.auth.UserAuthorizationLoginDTO; import com.czg.account.entity.ShopInfo; @@ -36,6 +37,11 @@ public class UserAuthorizationController { return CzgResult.success(userAuthorizationService.login(userAuthorizationLoginDTO)); } + @PostMapping + public CzgResult getPhone(@RequestBody @Validated GetPhoneDTO getPhoneDTO) { + return CzgResult.success(userAuthorizationService.getPhone(getPhoneDTO)); + } + /** * 通过code获取openId * @param code code diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/dto/auth/GetPhoneDTO.java b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/auth/GetPhoneDTO.java new file mode 100644 index 00000000..43e3f453 --- /dev/null +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/dto/auth/GetPhoneDTO.java @@ -0,0 +1,17 @@ +package com.czg.account.dto.auth; + +import lombok.Data; + +/** + * @author Administrator + */ +@Data +public class GetPhoneDTO { + /** + * 来源 alipay支付宝 wechat微信 + */ + private String source; + private String encryptedData; + private String code; + private String iv; +} diff --git a/cash-common/cash-common-service/src/main/java/com/czg/account/service/UserAuthorizationService.java b/cash-common/cash-common-service/src/main/java/com/czg/account/service/UserAuthorizationService.java index f2bf819d..2140e50e 100644 --- a/cash-common/cash-common-service/src/main/java/com/czg/account/service/UserAuthorizationService.java +++ b/cash-common/cash-common-service/src/main/java/com/czg/account/service/UserAuthorizationService.java @@ -1,5 +1,6 @@ package com.czg.account.service; +import com.czg.account.dto.auth.GetPhoneDTO; import com.czg.account.dto.auth.LoginTokenDTO; import com.czg.account.dto.auth.UserAuthorizationLoginDTO; @@ -10,4 +11,6 @@ public interface UserAuthorizationService { LoginTokenDTO login(UserAuthorizationLoginDTO userAuthorizationLoginDTO); String getOpenId(String code, String source); + + String getPhone(GetPhoneDTO getPhoneDTO); } diff --git a/cash-dependencies/pom.xml b/cash-dependencies/pom.xml index e67e8328..4e5e936a 100644 --- a/cash-dependencies/pom.xml +++ b/cash-dependencies/pom.xml @@ -38,6 +38,7 @@ 2.0.24 2.8.3 3.5.3 + 3.8.0 @@ -47,6 +48,11 @@ cash-common-tools ${project.version} + + com.github.binarywang + weixin-java-miniapp + ${weixin.java.miniapp.version} + com.google.zxing diff --git a/cash-service/account-service/pom.xml b/cash-service/account-service/pom.xml index 3dce1540..9badb240 100644 --- a/cash-service/account-service/pom.xml +++ b/cash-service/account-service/pom.xml @@ -18,6 +18,10 @@ + + com.github.binarywang + weixin-java-miniapp + com.github.whvcse easy-captcha diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/UserAuthorizationServiceImpl.java b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/UserAuthorizationServiceImpl.java index 5b60aa6a..ff67b9db 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/UserAuthorizationServiceImpl.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/service/impl/UserAuthorizationServiceImpl.java @@ -1,8 +1,12 @@ package com.czg.service.account.service.impl; +import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson2.JSONObject; +import com.alipay.api.AlipayApiException; +import com.czg.account.dto.auth.GetPhoneDTO; import com.czg.account.dto.auth.LoginTokenDTO; import com.czg.account.dto.auth.UserAuthorizationLoginDTO; import com.czg.account.dto.auth.WechatRawDataDTO; @@ -11,6 +15,7 @@ import com.czg.account.service.UserAuthorizationService; import com.czg.account.service.UserInfoService; import com.czg.enums.StatusEnum; import com.czg.enums.UserAuthSourceEnum; +import com.czg.exception.ApiNotPrintException; import com.czg.exception.CzgException; import com.czg.sa.MyStpLogic; import com.czg.sa.StpKit; @@ -41,12 +46,30 @@ public class UserAuthorizationServiceImpl implements UserAuthorizationService { String openId; if (UserAuthSourceEnum.WECHAT.getValue().equals(source)) { openId = wechatAuthUtil.getAccountOpenId(code); - }else { + } else { openId = alipayUtil.getOpenId(code, true); } return openId; } + @Override + public String getPhone(GetPhoneDTO phoneDTO) { + String mobile; + if (UserAuthSourceEnum.ALIPAY.getValue().equals(phoneDTO.getSource())) { + mobile = alipayUtil.getMobile(phoneDTO.getEncryptedData()); + } else { + String sessionKey = wechatAuthUtil.getSessionKey(phoneDTO.getCode(), "session_key"); + String data = WxMaCryptUtils.decrypt(sessionKey, phoneDTO.getEncryptedData(), phoneDTO.getIv()); + JSONObject jsonObject = JSONObject.parseObject(data); + if (jsonObject.containsKey("phoneNumber")) { + mobile = jsonObject.getString("phoneNumber"); + }else { + throw new ApiNotPrintException("手机号获取失败"); + } + } + return mobile; + } + @Override public LoginTokenDTO login(UserAuthorizationLoginDTO userAuthorizationLoginDTO) { diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/util/AlipayUtil.java b/cash-service/account-service/src/main/java/com/czg/service/account/util/AlipayUtil.java index 380bf07a..e48eb6e8 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/util/AlipayUtil.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/util/AlipayUtil.java @@ -1,11 +1,16 @@ package com.czg.service.account.util; import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; import com.alipay.api.AlipayConfig; import com.alipay.api.DefaultAlipayClient; +import com.alipay.api.internal.util.AlipayEncrypt; import com.alipay.api.request.AlipaySystemOauthTokenRequest; import com.alipay.api.response.AlipaySystemOauthTokenResponse; +import com.czg.exception.ApiNotPrintException; import com.czg.resp.CzgResult; import com.czg.system.dto.SysParamsDTO; import com.czg.system.service.SysParamsService; @@ -135,4 +140,30 @@ public class AlipayUtil { return response.getUserId(); } + public String getMobile(String encryptedData) { + if(StrUtil.isEmpty(encryptedData)){ + throw new RuntimeException("加密数据不能为空"); + } + try { + log.info("解密前的数据,返回结果:{}", encryptedData); + String resp = AlipayEncrypt.decryptContent(encryptedData, "AES", encryptKey, "UTF-8"); + log.info("解密后的数据,返回结果:{}", resp); + boolean isJson = JSONUtil.isTypeJSON(resp); + if(!isJson){ + throw new AlipayApiException("解密后的数据不是json格式"); + } + JSONObject jsonObject = JSONUtil.parseObj(resp); + String code = jsonObject.getStr("code"); + String msg = jsonObject.getStr("msg"); + String mobile = jsonObject.getStr("mobile"); + if("10000".equals(code)){ + return mobile; + }else{ + throw new AlipayApiException(code,msg); + } + }catch (AlipayApiException e){ + log.error("获取支付宝用户的手机号码失败,错误码:{},错误信息:{}", e.getErrCode(), e.getErrMsg()); + throw new RuntimeException(e); + } + } } diff --git a/cash-service/account-service/src/main/java/com/czg/service/account/util/WechatAuthUtil.java b/cash-service/account-service/src/main/java/com/czg/service/account/util/WechatAuthUtil.java index 4d223308..7a42dc69 100644 --- a/cash-service/account-service/src/main/java/com/czg/service/account/util/WechatAuthUtil.java +++ b/cash-service/account-service/src/main/java/com/czg/service/account/util/WechatAuthUtil.java @@ -10,7 +10,6 @@ import com.czg.system.service.SysParamsService; import jakarta.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.annotation.DubboReference; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.util.HashMap; @@ -23,7 +22,7 @@ import java.util.Map; @Slf4j @Component public class WechatAuthUtil { - @DubboReference + @DubboReference(check = false) private SysParamsService sysParamsService; // @Value("${wx.appId}") @@ -86,14 +85,14 @@ public class WechatAuthUtil { return JSONObject.parseObject(resp).getString("openid"); } - public String getSessionKeyOrOpenId(String code, boolean isAccount) { + public JSONObject getSession(String code) { String requestUrl = "https://api.weixin.qq.com/sns/jscode2session"; Map requestUrlParam = new HashMap<>(); // https://mp.weixin.qq.com/wxopen/devprofile?action=get_profile&token=164113089&lang=zh_CN //小程序appId - requestUrlParam.put("appid", isAccount ? accountAppId : appId); + requestUrlParam.put("appid", appId); //小程序secret - requestUrlParam.put("secret", isAccount ? accountSecrete : secrete); + requestUrlParam.put("secret", secrete); //小程序端返回的code requestUrlParam.put("js_code", code); //默认参数 @@ -102,11 +101,19 @@ public class WechatAuthUtil { String resp = HttpUtil.post(requestUrl, requestUrlParam); JSONObject jsonObject = JSON.parseObject(resp); log.info("微信获取openid响应报文:{}", resp); - String openid = jsonObject.getString("openid"); - if (StrUtil.isBlank(openid)) { - throw new RuntimeException("openId获取失败"); - } + return jsonObject; + } - return openid; + public String getSessionKey(String code, String key) { + JSONObject session = getSession(code); + String info = session.getString(key); + if (StrUtil.isBlank(info)) { + throw new RuntimeException(key + "获取失败"); + } + return info; + } + + public String getSessionKeyOrOpenId(String code, boolean isAccount) { + return getSessionKey(code, "openId"); } }