微信第三方平臺開發詳解——PHP版

微信第三方平臺開發詳解之申請以及全網發佈流程 html

微信第三方平臺開發詳解之受權流程 前端

微信第三方平臺開發詳解之代小程序開發數據庫

 

第一步,經過ComponentTicket獲取component_access_tokenjson

 

直接上代碼:小程序

由於ComponentAccessToken天天的獲取次數是有限制,博主也沒有測試過具體多少次。因此根據微信的提示作了個判斷當ComponentAccessToken的校驗時間戳小於當前時間戳180秒後,從新獲取一下ComponentAccessToken,下面是邏輯:api

  /**
     * 微信獲取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;
    }app

 

第二步、經過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的方法,以及介紹一些第三方代小程序開發的功能。

相關文章
相關標籤/搜索