Alipay アプレットはユーザー情報と携帯電話番号を取得します

Alipay アプレットはユーザー情報と携帯電話番号を取得します

ご存知のように、WeChat アプレットは WeChat 自体による認証後にログインでき、プラットフォームは WeChat アカウント情報を取得してデータベースに保存できます。同様に、Alipay アプレットの開発プロセスでは、ログイン機能の設計も可能です。
ここに画像の説明を挿入
これは公式が提供するタイミング図で、プロセスを詳しく見てみましょう

1. アプレット側でauth_codeを取得し、ユーザー認証コードを取得します。

2. 最初のステップで取得した認証コード auth_code を独自のバックグラウンドに渡します。これは、バックグラウンドが小さなプログラムの受信を容易にするインターフェースを記述する必要があることを意味します。

3. バックグラウンドで auth_code を取得した後、Alipay の認証プラットフォームを呼び出して、ユーザーの一意のトークンと Alipay のユーザー ID を取得する必要があります。呼び出しインターフェイスは alipay.system.oauth.token です

	// 服务端获取access_token、user_id
    private AlipaySystemOauthTokenResponse getAccessToken(String authCode) throws Exception {
    
    

        String code = JSON.parseObject(authCode).getString("authCode");

        // 1. 填入appid
        String APPID = "2021002147669716";
        // 2. 填入应用私钥
        String PRIVATE_KEY = "应用私钥";
        // 3. 填入支付宝公钥
        String ALIPAY_PUBLIC_KEY = "支付宝公钥";
        
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
                APPID,
                PRIVATE_KEY,
                "json",
                "GBK",
                ALIPAY_PUBLIC_KEY,
                "RSA2");
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        
        //授权方式:authorization_code,表示换取使用用户授权码code换取授权令牌access_token。
        request.setGrantType("authorization_code");
        // 4. 填入前端传入的授权码authCode
        //授权码,用户对应用授权后得到。本参数在 grant_type 为 authorization_code 时必填
        request.setCode(code);
        AlipaySystemOauthTokenResponse response = alipayClient.execute(request);

        if(response.isSuccess()){
    
    
            System.out.println("调用成功");
        } else {
    
    
            System.out.println("调用失败");
        }
        return response;
    }

3. ユーザーの一意のトークンと Alipay のユーザー ID を取得した後、インターフェースalipay.user.info.authを呼び出して、許可されたユーザーの基本情報を取得します。

	// 获取支付宝用户信息
    private AlipayUserInfoShareResponse getAliUserInfo (String accessToken) throws Exception {
    
    

		// 1. 填入appid
        String APPID = "2021002147669716";
        // 2. 填入应用私钥
        String PRIVATE_KEY = "应用私钥";
        // 3. 填入支付宝公钥
        String ALIPAY_PUBLIC_KEY = "支付宝公钥";

        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
                APPID ,
                PRIVATE_KEY,
                "json",
                "GBK",
                ALIPAY_PUBLIC_KEY,
                "RSA2");
        AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();

        AlipayUserInfoShareResponse response = alipayClient.execute(request, accessToken);
        if(response.isSuccess()){
    
    
            System.out.println("获取会员信息 - 调用成功");
            return response;
        }
        return null;
    }

4. 許可されたユーザー情報を取得してフロントエンドに返すだけでOKなので、ここにコードを貼り付けると、このインターフェイスでは上記の 2 つのメソッドが使用されます。

	/**
     * 获取用户授权
     */
    @ApiOperation(value = "用户授权")
    @PostMapping("/authCode")
    public AjaxResult authCode(@RequestBody String authCode) throws Exception {
    
    

        // 1. 服务端获取access_token、user_id
        AlipaySystemOauthTokenResponse response = getAccessToken(authCode);
        if (response.isSuccess()) {
    
    
            System.out.println("获取access_token - 调用成功!");

            //获取用户信息
            String accessToken = response.getAccessToken();
            String alipayUserId = response.getUserId();
            System.out.println("accessToken:" + accessToken);
            System.out.println("alipayUserId:" + alipayUserId);

            //通过支付宝api获取用户的信息
            AlipayUserInfoShareResponse aliUserInfo = getAliUserInfo(accessToken);
            if (aliUserInfo != null) {
    
    
                return AjaxResult.success(aliUserInfo);
            }
        }
        System.out.println("获取access_token - 调用失败!");
        return AjaxResult.error("获取access_token - 调用失败!");
    }

ここに画像の説明を挿入
上の図からわかるように、携帯電話番号のステップでバックグラウンドでmy.getPhoneNumberインターフェイスを呼び出す必要がある理由は、Alipay サーバーからアプレットに返されるコンテンツが暗号化されており、取得された AES 暗号化情報が暗号化されているためです。復号化する必要があります。
上記のプロセスは次のとおりです。

1. アプレット側は暗号化された RES 完全データを取得します。

2. 最初のステップで取得した完全な RES データを独自のバックグラウンドに転送するには、アプレットによって取得されたデータの復号化を容易にする別のインターフェイスを作成する必要があります。

	/**
     * 解密数据
     * @return
     */
    @ApiOperation(value = "解密数据")
    @PostMapping("/findPhone")
    public String findPhone(@RequestBody String jsonStr) throws Exception {
    
    

        //小程序前端提交的加密数据
        String response = JSON.parseObject(jsonStr).getString("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;
        //你的小程序对应的支付宝公钥(为扩展考虑建议用appId+signType做密钥存储隔离)
        String signVeriKey = "";
        //你的小程序对应的加解密密钥(为扩展考虑建议用appId+encryptType做密钥存储隔离)
        String decryptKey = "";

        //如果是加密的报文则需要在密文的前后添加双引号
        if (isDataEncrypted) {
    
    
            signContent = "\"" + signContent + "\"";
        }
        try {
    
    
            signCheckPass = AlipaySignature.rsaCheck(signContent, sign, signVeriKey, charset, signType);
        } catch (AlipayApiException e) {
    
    
            //验签异常, 日志
        }
        if(!signCheckPass) {
    
    
            //验签不通过(异常或者报文被篡改),终止流程(不需要做解密)
            throw new Exception("验签失败");
        }

        //3. 解密
        String plainData = null;
        if (isDataEncrypted) {
    
    
            try {
    
    
                plainData = AlipayEncrypt.decryptContent(content, encryptType, decryptKey, charset);
            } catch (AlipayApiException e) {
    
    
                //解密异常, 记录日志
                throw new Exception("解密异常");
            }
        } else {
    
    
            plainData = content;
        }
        return plainData;
    }

良いことの法則:すべては最終的には良いことになる、それが良いことではない場合、それはまだ終わりではないことを意味します。

おすすめ

転載: blog.csdn.net/Cike___/article/details/118221017