微信第三方平台开发详解——PHP版

微信第三方平台开发详解之申请以及全网发布流程

微信第三方平台开发详解之授权流程

微信第三方平台开发详解之代小程序开发

 

第一步,通过ComponentTicket获取component_access_token

 

直接上代码:

因为ComponentAccessToken每天的获取次数是有限制,博主也没有测试过具体多少次。所以根据微信的提示做了个判断当ComponentAccessToken的校验时间戳小于当前时间戳180秒后,重新获取一下ComponentAccessToken,下面是逻辑:

  /**
     * 微信获取ComponentAccessToken
     * @access public
     *
     */
    public function getComponentAccessToken()
    {
        $returnArray = array();
        //这里'type'是不同类型的AccessToken,我这边有小程序、公众号、第三方平台的,所以用'type'区分开来,2代表第三方平台
        //获取最新的第三方平台的AccessToken
        $wxAccessToken = self::where(array('type'=>2))->order(array('id'=>'desc'))->limit(1)->select();
        if($wxAccessToken){
            $wxAccessToken = $wxAccessToken[0]->toArray();
            //判断是否过期
            if((time() - $wxAccessToken['check_time']) < -180){
                
                $returnArray = array(
                    'code' => 1,
                    'info' => array(
                        'access_token' => $wxAccessToken['access_token'],
                        'end_time' => $wxAccessToken['check_time']
                    )
                );
            }else{
                //过期了重新获取
                $returnArray = self::setComponentAccessToken();
            }
        }else{
            //没有AccessToken重新获取
            $returnArray = self::setComponentAccessToken();
        }
        
        return $returnArray;
    }

 

这是重新获取ComponentAccessToken的核心代码

 /**
     * 通过component_verify_ticket获取component_access_token并保存
     * @access public
     *
     */
    public function setComponentAccessToken()
    {
        $returnArray = array();
        //初始化ComponentTicket模型(保存微信每10分钟传过来的ComponentTicket)
        $wxComponentTicketModel = new \app\diuber\model\WxComponentTicket();
        //获取数据库中最新的一个ComponentTicket
        $componentTicketRow = $wxComponentTicketModel->order(array('id'=>'desc'))->limit(1)->select();
        if($componentTicketRow){
            $componentTicket = $componentTicketRow[0]->toArray();
            
            $row = json_encode(array(
                'component_appid' => $this->appid,
                'component_appsecret' => $this->appsecret,
                'component_verify_ticket' => $componentTicket['component_verify_ticket']
            ));
            $url = 'https://api.weixin.qq.com/cgi-bin/component/api_component_token';
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $row);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            $output = curl_exec($ch);
            curl_close($ch);
            
            $output = json_decode($output, true);
            if(!empty($output['component_access_token']) && !empty($output['expires_in'])){
                $checkTime= time() + $output['expires_in'];
                $data = array(
                    'access_token' => $output['component_access_token'], //AccessToken
                    'type' => 2,//类型(1.小程序  2.第三方平台 3.公众号)
                    'create_time' => date('Y-m-d H:i:s'),
                    'check_time' =>  $checkTime //校验时间戳
                );
                //创建AccessToken记录
                $wx = self::create($data);
                if(!$wx){
                    $returnArray = array(
                        'code' => 0,
                        'info' => '后台保存失败!'
                    );
                }else{
                    $returnArray = array(
                        'code' => 1,
                        'info' => array(
                            'access_token' => $data['access_token'],
                            'end_time' => $data['check_time']
                        )
                    );
                }
            }else{
                $returnArray = array(
                    'code' => 0,
                    'info' => '微信端获取失败!'
                );
            }
        }
        
        return $returnArray;
    }

 

第二步、通过component_access_token获取预授权码pre_auth_code

代码如下:这个预授权码是为了获取正式授权码准备的,使用一次就会失效,所以没有去做缓存

  /**
     * 通过component_access_token获取pre_auth_code
     * @access public
     *
     */
    public function getPreAuthCode()
    {
        $returnArray = array();
        //获取component_access_token
        $componentAccessTokenRow = self::getComponentAccessToken();
        if($componentAccessTokenRow['code'] == 1){
            $componentAccessToken = $componentAccessTokenRow['info']['access_token'];
        
            $row = json_encode(array(
                'component_appid' => $this->appid
            ));
            $url = 'https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token='.$componentAccessToken;
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $row);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            $output = curl_exec($ch);
            curl_close($ch);
            $returnArray = array(
                'code' => 1,
                'info' => json_decode($output, true)
            );
        }else{
            $returnArray = array(
                'code' => 0,
                'info' => '获取component_access_token失败'
            );
        }
        
        return $returnArray;
    }

第三步、通过预授权码获取授权码

代码: 这是控制器中的方法

/**
     * 发起授权页的体验URL获取预授权码
     * @access public
     *
     */
    public function auth()
    {
        $url = '';
        $wxAccessTokenModel = new \app\diuber\model\WxAccessToken();
        //获取预授权码
        $preAuthCodeRow = $wxAccessTokenModel->getPreAuthCode();
        if($preAuthCodeRow['code'] == 1){
            if(!empty($preAuthCodeRow['info']['pre_auth_code'])){
                $preAuthCode = $preAuthCodeRow['info']['pre_auth_code'];
                //拼接获取预授权码的URL
                $url = 'https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid='.$this->appId.'&pre_auth_code='.$preAuthCode.'&redirect_uri=https://xx.xxxx.com/xxxx/wx_third_plat/getAuthCode';
            }
        }
        

        //传入前端的URL
        $this->assign('url', $url);
        return $this->fetch('auth');
    }

 

前端 auth.html:

<a href="{$url}" id="authurl" style="display: inline;">
<img src="https://open.weixin.qq.com/zh_CN/htmledition/res/assets/res-design-download/icon_button3_1.png">
</a>

点击授权跳转到微信公众平台授权,用户扫描授权之后会跳回到你在auth方法中的redirect_uri,并且会带上授权auth_code,注意这里的auth_code是带在url中的需要用GET获取,

redirect_uri中的方法(https://xx.xxxx.com/xxxx/wx_third_plat/getAuthCode),代码如下:

  /**
     * 获取用户授权码getAuthCode
     * @access public
     *
     */
    public function getAuthCode()
    {
        self::checkCompanyID();
        $result = array();

        //实例化WxAccessToken模型,需要用到这个model中的getMiniAppInfo方法
        $wxAccessTokenModel = new \app\diuber\model\WxAccessToken();
        if(!empty($_GET)){
            if(!empty($_GET['auth_code'])){
                $result = $wxAccessTokenModel->getMiniAppInfo($_GET['auth_code'], $this->companyId);
            }
        }
        $this->redirect('adminSetting/index');
    }

 

getMiniAppInfo方法:

  /**
     * 通过授权码换取小程序的接口调用凭据和授权信息并保存
     * @param $companyId 公司编号 区分不同小程序授权账号
     * @access public
     *
     */
    public function getMiniAppInfo($authCode, $companyId = 0)
    {
        $returnArray = array();
        $wxComponentTicketModel = new \app\diuber\model\WxComponentTicket();
        $wxAuthorizerModel = new \app\diuber\model\WxAuthorizer();
        //获取ComponentAccessToken
        $componentAccessTokenRow = self::getComponentAccessToken();
        
        if($componentAccessTokenRow['code'] == 1){
            $componentAccessToken = $componentAccessTokenRow['info']['access_token'];
            if($authCode){
                $row = json_encode(array(
                    'component_appid' => $this->appid,
                    'authorization_code' => $authCode
                ));
                //通过授权码获取公众号或小程序的接口调用凭据和授权信息
                $url = 'https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token='.$componentAccessToken;
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, $url);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($ch, CURLOPT_POST, 1);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $row);
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                $output = curl_exec($ch);
                curl_close($ch);
                $output = json_decode($output, true);
                
                //判断授权信息并且存入数据库中
                if(!empty($output['authorization_info'])){
                    if($companyId){
                        $output['authorization_info']['company_id'] = $companyId;
                        $authResult = $wxAuthorizerModel->setMiniAppInfo($output['authorization_info']);
                        if($authResult['code'] == 1){
                            $returnArray = array(
                                'code' => 1,
                                'info' => $output['authorization_info']
                            );
                        }else{
                            $returnArray = array(
                                'code' => 0,
                                'info' => 'create or update mini app cgi info fail'
                            );
                        }
                    }else{
                        $returnArray = array(
                            'code' => 1,
                            'info' => $output['authorization_info']
                        );
                    }
                }else{
                    $returnArray = array(
                        'code' => 0,
                        'info' => 'not found authorization_info'
                    );
                }
            }else{
                $returnArray = array(
                    'code' => 0,
                    'info' => 'not found $authCode'
                );
            }
        }else{
            $returnArray = array(
                'code' => 0,
                'info' => 'get component_access_token fail'
            );
        }
        
        return $returnArray;
    }

 

setMiniAppInfo方法: 

  /**
     * 保存小程序的接口调用凭据和授权信息
     * @access public
     *
     */
    public function setMiniAppInfo($data)
    {
        $returnArray = array();
        if($data){
            if(!empty($data['authorizer_appid']) && !empty($data['authorizer_access_token']) && !empty($data['authorizer_refresh_token']) && !empty($data['func_info']) && !empty($data['expires_in']) && !empty($data['company_id'])){
                $result = '';
                //判断用户是否已经授权过
                $existInfo = self::get(array('authorizer_appid'=>$data['authorizer_appid']));
                if($existInfo){
                    //已授权
                    $existInfo = $existInfo->toArray();
                    if((time() - $existInfo['check_time']) < 6800){
                        //授权时间已经超过6800秒,更新
                        $row = array(
                            'authorizer_appid' => $data['authorizer_appid'],
                            'authorizer_access_token' => $data['authorizer_access_token'],
                            'authorizer_refresh_token' => $data['authorizer_refresh_token'],
                            'func_info' => json_encode($data['func_info']),
                            'update_time' => date('Y-m-d H:i:s'),
                            'check_time' => ($existInfo['check_time'] + $data['expires_in']),
                            'company_id' => $data['company_id']
                        );
                        $result = self::update($row, array('id'=>$existInfo['id']));
                    }else{
                        //授权时间已经超过6800秒,不作操作
                        $result = '没有超时,不用更新';
                    }
                }else{
                    //未授权,新增授权信息
                    $row = array(
                        'authorizer_appid' => $data['authorizer_appid'],
                        'authorizer_access_token' => $data['authorizer_access_token'],
                        'authorizer_refresh_token' => $data['authorizer_refresh_token'],
                        'func_info' => json_encode($data['func_info']),
                        'create_time' => date('Y-m-d H:i:s'),
                        'check_time' => (time() + $data['expires_in']),
                        'company_id' => $data['company_id']
                    );
                    $result = self::create($row);
                }
                if($result){
                    $returnArray = array(
                        'code' => 1,
                        'info' => '创建或者更新成功'
                    );
                }
            }else{
                $returnArray = array(
                    'code' => 0,
                    'info' => 'data格式不正确'
                );
            }
        }
        
        return $returnArray;
    }

到这里已经获取到公众号或者小程序的授权信息,包括授权小程序的appid:authorizer_appid、授权小程序的AccessToken:authorizer_access_token、授权小程序的刷新code:authorizer_refresh_token 以及授权给开发者的权限集列表,具体权限查看微信文档。注意这个授权AccessToken有效时间是7200秒所以需要做好刷新AccessToken的方法。

下一章会增加刷新授权AccessToken的方法,以及介绍一些第三方代小程序开发的功能。

 

 

转载于:https://my.oschina.net/u/3463279/blog/1558749

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值