小程序(公众号)授权给第三方平台流程实现(Java)

2,734 阅读4分钟

微信第三方平台开发

1、名词解释

1.1、开放平台相关

名词释义
component_appid第三方平台的appid
component_appsecret第三方平台的秘钥
component_verify_ticket验证票据
component_access_token第三方平台的访问令牌

1.2、授权相关

名词释义
authorizer_appid授权方appid
authorizer_access_token授权方调用令牌
authorizer_refresh_token授权方调用令牌失效后的刷新令牌
pre_auth_code预授权码,跳转到授权页的时候,必须携带这个参数

2、开发流程

2.1、注册开放平台

登录[微信第三方平台官方网址](https://open.weixin.qq.com/)填写申请信息并注册开发账号。获取到第三方平台的APPID和APPSECRET。

2.2、创建第三方平台,在这里填写了几个关键参数

授权发起页域名:发起授权的时候只能从这个域名发起,其他的一律不通过
授权事件接收URL:接收微信推送的授权相关信息
消息校验Token:开发者在代替公众号或小程序接收到消息时,用此Token来校验消息。
消息加解密Key:在代替公众号或小程序收发消息过程中使用。必须是长度为43位的字符串,只能是字母和数字。 消息与事件接收URL:通过该URL接收公众号或小程序消息和事件推送,该参数按规则填写(需包含/APPID)。

2.3、java开发

微信开放平台官方文档

1、导入依赖

    <dependency>
        <groupId>com.github.binarywang</groupId>
        <artifactId>weixin-java-open</artifactId>
        <version>3.7.0</version>
    </dependency>

2、在项目中配置第三方平台的开发信息(APPID、APPSECRET、消息校验Token、消息加解密Key);授权事件接收URL中的域名要与授权发起页域名保持一致。

授权事件接口:

	/**
     *  授权事件接收URL
     *      用于接收取消授权通知、授权成功通知、授权更新通知,也用于接收验证票据
     * @param timestamp 事件戳
     * @param nonce 随机数
     * @param encType 加密类型,为 aes
     * @param msgSignature  消息体签名
     * @param postData  密文,对应POST请求的数据
     */
    @PostMapping("/receive")
    public String receiveWxEvent(@RequestParam("timestamp") String timestamp,
                                      @RequestParam("nonce") String nonce,
                                      @RequestParam(name = "encrypt_type", required = false) String encType,
                                      @RequestParam(name = "msg_signature", required = false) String msgSignature,
                                      @RequestBody(required = false) String postData) {
        log.info("=========================开始-接收微信服务器的授权事件接收URL=========================");

        log.info("\n授权事件接收URL接收微信请求:【encType=[{}], 消息体签名msgSignature=[{}], 时间戳timestamp=[{}], 随机数nonce=[{}], postData=[\n{}\n]】",
                encType, msgSignature, timestamp, nonce, postData);
        try {
            //解密消息
            WxOpenXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedXml(postData,
                    wxOpenConfigStorage, timestamp, nonce, msgSignature);
            String infoType = inMessage.getInfoType();
            

			//infoType:验证票据、新增授权、更新授权、取消授权,这里可以根据不同类型做业务逻辑处理
             
            

        } catch (Exception e) {
            e.printStackTrace();
            log.error("解析微信服务器的授权事件信息异常,【{}】",e.getMessage());
        }
        log.info("=========================结束-接收微信服务器的授权事件接收URL=========================");
        return "success";

    }

消息与事件接收接口: 主要接收授权小程序的回调信息,审核通知等。

/**
     *  消息与事件接收URL
     *      该 URL 用于接收已授权公众号的消息和事件,消息内容、消息格式、签名方式、加密方式与普通公众号接收的一致,
     *      唯一区别在于签名 token 和加密 symmetric_key 使用的是服务方申请时所填写的信息。由于消息具体内容不会变更,
     *      故根据消息内容里的 ToUserName,服务方是可以区分出具体消息所属的公众号
     * @param postData
     * @param appId
     * @param signature
     * @param timestamp
     * @param nonce
     * @param openid
     * @param encType
     * @param msgSignature
     * @return
     */
    @PostMapping("/{appId}/callback")
    public Object callback(@RequestBody(required = false) String postData,
                           @PathVariable("appId") String appId,
                           @RequestParam("signature") String signature,
                           @RequestParam("timestamp") String timestamp,
                           @RequestParam("nonce") String nonce,
                           @RequestParam("openid") String openid,
                           @RequestParam("encrypt_type") String encType,
                           @RequestParam("msg_signature") String msgSignature) {
        log.info("=========================开始-接收微信服务器的消息与事件接收URL=========================");
        log.info(
                "\n消息与事件接收URL接收微信请求:【appId=[{}], openid=[{}], signature=[{}], encType=[{}], msgSignature=[{}],"
                        + " timestamp=[{}], nonce=[{}], postData=[\n{}\n]】",
                appId, openid, signature, encType, msgSignature, timestamp, nonce, postData);

        try {
            //解密消息
            WxMpXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedMpXml(postData,
                    wxOpenConfigStorage, timestamp, nonce, msgSignature);
            
        } catch (Exception e) {
            e.printStackTrace();
            log.error("解析微信服务器的消息与事件信息异常,【{}】",e.getMessage());
        }
        log.info("=========================结束-接收微信服务器的消息与事件接收URL=========================");
        return "success";
    }

注意事项:

由于微信推送服务器过多的问题,会导致验证票据等数据重复推送,如果需要手动调用获取第三方平台token,则需将最近的几次票据进行持久化处理后,利用spring重试机制尝试多次获取token,直到获取有效token为止。

3、小程序授权成功后,第三方平台有权限调用小程序的相关接口(通过authorizer_access_token),例如小程序的登录的接口。