无关风月
2024-09-10 caa2b51bb4133f5a2e59eac242e744fb57f864a0
ruoyi-service/ruoyi-account/src/main/java/com/ruoyi/account/ali/tools/AliAppletTools.java
@@ -1,8 +1,24 @@
package com.ruoyi.account.ali.tools;
import com.alibaba.fastjson.JSON;
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.AlipayConfig;
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.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import com.ruoyi.account.ali.Constant.AliConstant;
import com.ruoyi.account.ali.model.AliProperties;
import com.ruoyi.common.core.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
/**
 * @author xiaochen
@@ -13,8 +29,14 @@
@Slf4j
public class AliAppletTools {
    private static final String SERVER_URL = "https://openapi.alipay.com/gateway.do";
    //设置连接池中的最大可缓存的空闲连接数
    private static final Integer MaxIdleConnections = 5;
    //连接超时,单位:毫秒,默认3000
    private static final Integer ConnectTimeout = 3000;
    //读取超时,单位:毫秒,默认15000
    private static final Integer ReadTimeout = 15000;
    //空闲连接存活时间,单位:毫秒,默认10000L
    private static final Long KeepAliveDuration = 10000L;
    private AliProperties aliProperties;
    public AliAppletTools(AliProperties aliProperties) {
@@ -22,15 +44,104 @@
    }
    /**
     * 支付宝小程序授权登录接口
     * @param code
     * @return
     */
    public AlipaySystemOauthTokenResponse login(String code) {
        try {
            // 初始化SDK
            AlipayClient alipayClient = new DefaultAlipayClient(new AliAppletTools(aliProperties).getAlipayConfig(AliConstant.LOGIN_SERVER_URL));
            // 构造请求参数以调用接口
            AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
            // 设置授权码
            request.setCode(code);
            // 设置授权方式
            request.setGrantType(AliConstant.GRANT_TYPE);
            return alipayClient.execute(request);
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 支付宝小程序授权获取手机号
     * @return
     */
    public AlipayUserInfoShareResponse getUserInfo(String accessToken) {
        try {
            // 初始化SDK
            AlipayClient alipayClient = new DefaultAlipayClient(new AliAppletTools(aliProperties).getAlipayConfig(AliConstant.LOGIN_SERVER_URL));
            //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.user.userinfo.share
            AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
            //授权类接口执行API调用时需要带上accessToken
            return alipayClient.execute(request,accessToken);
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 获取用户手机号
     * @param response
     * @return
     */
    public String getPhoneNumber(String response){
        //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;
        if (isDataEncrypted) {
            signContent = "\"" + signContent + "\"";
        } try {
            signCheckPass = AlipaySignature.rsaCheck(signContent, sign, aliProperties.getAlipayPublicKey(), charset, signType);
        } catch (AlipayApiException e) {
            // 验签异常, 日志
        } if (!signCheckPass) {
            //验签不通过(异常或者报文被篡改),终止流程(不需要做解密)
            throw new ServiceException("验签失败");
        }
        //3. 解密
        String plainData = null;
        if (isDataEncrypted) {
            try {
                plainData = AlipayEncrypt.decryptContent(content, encryptType, "XABBSOeWDakvuG9TDez4Qg====", charset);
            } catch (AlipayApiException e) {
                //解密异常, 记录日志
                throw new ServiceException("解密异常");
            }} else {
            plainData = content;
        }
        log.info("解密后的数据:{}", plainData);
        String phoneNumber = "";
        if (plainData.contains("mobile")) {
            phoneNumber = JSON.parseObject(plainData).getString("mobile");
        }
        return phoneNumber;
    }
    /**
     * 初始化支付宝配置
     * @return
     */
    public AlipayConfig getAlipayConfig() {
    public AlipayConfig getAlipayConfig(String serverUrl) {
        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl(SERVER_URL);
        alipayConfig.setServerUrl(serverUrl);
        alipayConfig.setAppId(aliProperties.getAppId());
        alipayConfig.setPrivateKey(aliProperties.getPrivateKey());
        alipayConfig.setAlipayPublicKey(aliProperties.getAlipayPublicKey());
        alipayConfig.setMaxIdleConnections(MaxIdleConnections);
        alipayConfig.setConnectTimeout(ConnectTimeout);
        alipayConfig.setReadTimeout(ReadTimeout);
        alipayConfig.setKeepAliveDuration(KeepAliveDuration);
        return alipayConfig;
    }