Alipay applet obtains user information and mobile phone number

Alipay applet obtains user information and mobile phone number

As we all know, WeChat applets can be logged in after authorization by WeChat itself, and the platform can obtain WeChat account information and save them in the database. Similarly, in the development process of Alipay applets, the design of the login function can also be done. So
insert image description here
this is the timing diagram provided by the official, let's take a look at the process in detail:

1. Obtain auth_code on the applet side to obtain the user authorization code

2. Pass the authorization code auth_code obtained in the first step to our own background, which means that the background needs to write an interface to facilitate the incoming of the small program

3. After getting the auth_code in the background, it needs to call Alipay’s authorization platform to obtain the user’s unique token and Alipay’s userid, both of which are unique. The calling interface is 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. After obtaining the user's unique token and Alipay's userid, we call the interface alipay.user.info.auth to obtain the basic information of the authorized user.

	// 获取支付宝用户信息
    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. It is OK to obtain the authorized user information, and then return it to the front end. Paste the code here, and the above two methods are used in this interface.

	/**
     * 获取用户授权
     */
    @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 - 调用失败!");
    }

insert image description here
As can be seen from the figure above, the reason why the mobile phone number step requires us to call the my.getPhoneNumber interface in the background is because the content returned by the Alipay server to the applet is encrypted, and the obtained AES encrypted information needs to be decrypted.
Not much to say, the above process:

1. The applet side obtains the encrypted RES complete data.

2. To transfer the complete RES data obtained in the first step to our own background, we need to write another interface to facilitate the decryption of the data obtained by the applet

	/**
     * 解密数据
     * @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;
    }

The law of good things: Everything will be a good thing in the end, if it is not a good thing, it means that it is not the end yet.

Guess you like

Origin blog.csdn.net/Cike___/article/details/118221017