我院新闻
支付宝小程序授权登录 (Java 后台篇)
发布时间:2024-01-23
支付宝小程序授权登录 (Java 后台篇)
开始 :

实现支付宝小程序授权登录功能, 本文主要是介绍支付宝小程序授权登录流程,与关键登录与处理代码.


流程 :


关键代码 :

1.获取用户信息

	/**
     * (支付宝) 换取授权访问令牌
     * @param grantType 必选 授权方式
     * @param code 可选 授权码
     * @param refreshToken 可选 刷新令牌
     * @return
     */
    private Map getAuthToken(String grantType,String code,String refreshToken) throws AlipayApiException {
    
        AlipayClient alipayClient = new DefaultAlipayClient(
                "https://openapi.alipay.com/gateway.do",  // 请求支付宝网关地址,建议定义为常量保存
                appId,     								  // 小程序APPID,建议存储在配置中心中,动态获取.
               	secretKey ,								  // 小程序密钥,建议存储在配置中心中,动态获取.
                "json",									  // 仅支持JSON
                "charset",								  // 请求使用的编码格式,如utf-8,gbk,gb2312等
                publicKey,								  // 小程序公钥,建议存储在配置中心中,动态获取.
                signType);								  // 商户生成签名字符串所使用的签名算法类型,推荐使用RSA2
                
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
		// 构建请求参数
        request.setGrantType(grantType);
        request.setCode(code);
        if(ObjectUtils.isNotEmpty(grantType)){
            request.setGrantType(grantType);
        }else if(ObjectUtils.isNotEmpty(refreshToken)){
            request.setRefreshToken(refreshToken);
        }

        // 响应
        AlipaySystemOauthTokenResponse response = alipayClient.execute(request);
        if(response.isSuccess()){
            log.info("[AlipaySystemOauthTokenResponse] >>>> Succeed!");
            return BeanConvertUtils.objectToMap(JSON.parseObject(response.getBody()));
        } else {
            log.error("[AlipaySystemOauthTokenResponse] = Fail! Cause:{}",response.getSubMsg());
            throw new AlipayApiException("获取支付宝信息失败,请稍后再试!");
        }
    }

2.获取用户手机号

/**
     * 用户信息解密
     * @param data 前端传递的加密数据
     * @return
     * @throws Exception
     */
    private Map infoDecode(String data) throws Exception {
        // 1. 获取验签和解密所需要的参数
        Map<String, String> openapiResult =
                JSON.parseObject(data, new TypeReference<Map<String, String>>() {}, Feature.OrderedField);

        // 加签算法
        String signType = "RSA2";
        // 验签和解密用的字符集
        String charset = AliConstant.CHARSET;
        // 加密算法
        String encryptType = "AES";
        // 返回码
        String code = "code";
        String sign = openapiResult.get("sign");
        String content = openapiResult.get("response");
        // 是否加密
        boolean isDataEncrypted = !content.startsWith("{");
        // 是否验签通过
        boolean signCheckPass = false;

        // 2. 验签
        String signContent = content;

        /**
         * 小程序对应的支付宝公钥(为扩展考虑建议用appId+signType做密钥存储隔离)
         * 小程序对应的加解密密钥(为扩展考虑建议用appId+encryptType做密钥存储隔离)
         */
        String signVeriKey = aliConfig.getPublicKey();
        String decryptKey = aliConfig.getDecryptKey();
        // 如果是加密的报文则需要在密文的前后添加双引号
        if (isDataEncrypted) {
            signContent = "\"" + signContent + "\"";
        }
        try {
            signCheckPass = AlipaySignature.rsaCheck(signContent, sign, signVeriKey, charset, signType);
        } catch (AlipayApiException e) {
            // 验签异常
            log.error("支付宝解密用户信息 >>> 验签异常:{}",e.getMessage());
        }
        // 验签不通过(异常或者报文被篡改),终止流程(不需要做解密)
        if (!signCheckPass) {
            throw new AlipayApiException("验签失败");
        }
        // 3. 解密
        String plainData = null;
        if (isDataEncrypted) {
            try {
                plainData = AlipayEncrypt.decryptContent(content, encryptType, decryptKey, charset);
            } catch (AlipayApiException e) {
                // 解密异常, 记录日志
                log.error("Decode Abnormal:{}",e.getMessage());
                throw new AlipayApiException("解密异常");
            }
        } else {
            plainData = content;
        }
        // 自定义转换 String 转 Map
        Map map = BeanConvertUtils.objectToMap(JSON.parseObject(plainData));
        if (map != null && AliConstant.SUCCEED_CODE.equals(map.get(code))) {
            return map;
        }else{
            log.error("Decode Fail :{}",map);
            throw new AlipayApiException("解密失败");
        }
    }

关键参数指南 :

AppId : 支付宝开放平台 ⇒ 控制台 ⇒ 左上角

公钥密钥: 支付宝开放平台 ⇒ 控制台 ⇒ 开发设置 ⇒ 接口加签方式(密钥/证书)
(如图所示:)

加密解密密钥: 支付宝开放平台 ⇒ 控制台 ⇒ 开发设置 ⇒ 接口内容加密方式(密钥/证书)
(如图所示:)

调用相关接口也需要开通相关权限(需要填写资料):


[返回上级]