[php] 微信开放平台受权和全网发布

来源:互联网 发布:linux sleep 精度 编辑:程序博客网 时间:2024/05/22 10:45
一.

 授权流程

 1. 接收component_verify_ticket:

 [1]微信服务器每隔10分钟会向第三方的消息接收地址推送一次component_verify_ticket,拿到后需要在本地做好存储;

 [2]微信第三方平台的消息是加密的(下图),需要进行解密才能获取需要的信息;

 [3]接收并解密消息,代码如下:

/**     * 授权事件接收URL     */    public function msg() {        import("@.ORG.ArrayTool");        import("@.ORG.Weixincrypt.WXBizMsgCrypt");        $timestamp = empty($_GET ['timestamp']) ? '' : trim($_GET ['timestamp']);        $nonce = empty($_GET ['nonce']) ? '' : trim($_GET ['nonce']);        $msgSign = empty($_GET ['msg_signature']) ? '' : trim($_GET ['msg_signature']);        $signature = empty($_GET ['signature']) ? '' : trim($_GET ['signature']);        $encryptType = empty($_GET ['encrypt_type']) ? '' : trim($_GET ['encrypt_type']);        $encryptMsg = file_get_contents('php://input');        $wxData = C("platform_setting");        $encodingAesKey = $wxData['encodingAesKey'];        $token = $wxData['token'];        $appId = $wxData['appId'];        $Wxcrypt = new WXBizMsgCrypt($token, $encodingAesKey, $appId);        $postArr = ArrayTool::xml2array($encryptMsg);        $format = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%s]]></Encrypt></xml>";        $fromXml = sprintf($format, $postArr['Encrypt']);        //第三方收到公众号平台发送的消息        $msg = '';        $errCode = $Wxcrypt->decryptMsg($msgSign, $timestamp, $nonce, $fromXml, $msg); // 解密        if ($errCode == 0) {            $param = ArrayTool::xml2array($msg);            switch ($param['InfoType']) {                case 'component_verify_ticket' :    // 授权凭证                    $componentVerifyTicket = $param['ComponentVerifyTicket'];                    S('component_verify_ticket_' . $appId, $componentVerifyTicket);                    break;                case 'unauthorized' :               // 取消授权                    break;                case 'authorized' :                 // 授权                    break;                case 'updateauthorized' :           // 更新授权                    break;            }        }        exit("success");    }

 2.获取component_access_token:

 [1]每个令牌是存在有效期(2小时)的,且令牌的调用不是无限制的,请第三方平台做好令牌的管理,在令牌快过期时(比如1小时50分)再进行刷新。所以要对component_access_token做好本地缓存,代码如下:

$wxData = C("setting");        //1. 取得component_verify_ticket        $vt = S('component_verify_ticket_' . $wxData['appId']);        $at = S('component_access_token_' . $wxData['appId']);        //2. 获取第三方平台component_access_token        if (empty($at) && !empty($vt)) {            $url2 = "https://api.weixin.qq.com/cgi-bin/component/api_component_token";            $post = array();            $post['component_appid'] = $wxData['appId'];            $post['component_appsecret'] = $wxData['appSecret'];            $post['component_verify_ticket'] = $vt;            $return2 = $this->curlPost($url2, $post);            if (isset($return2['component_access_token'])) {                $at = $return2['component_access_token'];                S('component_access_token_' . $wxData['appId'], $at, 6600); //缓存1小时50分钟 = 6600秒            } else {                return false;            }        }

 3.获取pre_auth_code(注意这是预授权码,不是授权码):

$wxData = C('platform_setting');        $appId = $wxData['appId'];        $HT = new HttpTool();        $at = $HT->getComponentAccessToken();        if ($at) {            //3.获取预授权码pre_auth_code            $url3 = "https://api.weixin.qq.com/cgi-bin/component/api_create_preauthcode?component_access_token={$at}";            $post = array();            $post['component_appid'] = $appId;            $return3 = $HT->curlPost($url3, $post);            if (isset($return3['pre_auth_code'])) {                $preauthcode = $return3['pre_auth_code'];                $redirectUrl = C('site_url') . U("User/App/setauth", array('uid' => $uid));                $weixinUrl = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid={$appId}&pre_auth_code={$preauthcode}&redirect_uri={$redirectUrl}";                redirect($weixinUrl);                exit;            }        }        $this->error("亲, 授权失败了!");

 4.使用授权码换取公众号的接口调用凭据和授权信息:

//1. 使用授权码换取公众号的接口调用凭据和授权信息        import("@.ORG.HttpTool");        $HT = new HttpTool();        $wxData = C('platform_setting');        $caccessToken = $HT->getComponentAccessToken();        $url1 = "https://api.weixin.qq.com/cgi-bin/component/api_query_auth?component_access_token={$caccessToken}";        $post = array();        $post['component_appid'] = $wxData['appId'];        $post['authorization_code'] = $authcode;        $return = $HT->curlPost($url1, $post);        if (isset($return['authorization_info'])) {            $authinfo = $return['authorization_info'];            $authid = $authinfo['authorizer_appid'];            $accessToken = $authinfo['authorizer_access_token'];            $refreshToken = $authinfo['authorizer_refresh_token'];            //$funcInfo = $authinfo['func_info'];            //2. 获取授权方的公众号帐号基本信息            $url2 = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_info?component_access_token={$caccessToken}";            $post = array();            $post['component_appid'] = $wxData['appId'];            $post['authorizer_appid'] = $authid;            $return2 = $HT->curlPost($url2, $post);            if (isset($return2['authorizer_info'])) {                $wxinfo = $return2['authorizer_info'];                $fcinfo = $return2['authorization_info'];                $Wxuser = M("Wxuser");                //是否已经存在                $extFilter = array();                $wxuser['uid'] = $uid;                $extFilter['auth_appid'] = $fcinfo['authorizer_appid'];                $isExt = $Wxuser->where($extFilter)->find();                $wxuser = array();                $wxuser['uid'] = $uid;                $wxuser['token'] = $this->getToken();                $wxuser['wxid'] = $wxinfo['user_name'];     //原始ID                $wxuser['wxname'] = $wxinfo['nick_name'];   //昵称                $wxuser['weixin_type'] = $wxinfo['service_type_info']['id'];  //微信类型 授权方公众号类型,0代表订阅号,1代表由历史老帐号升级后的订阅号,2代表服务号                $wxuser['weixin'] = $wxinfo['alias'];       //微信号                $wxuser['headerpic'] = $wxinfo['head_img']; //头像                $wxuser['bind_type'] = 1;                $wxuser['auth_appid'] = $fcinfo['authorizer_appid'];                $wxuser['auth_access_token'] = $accessToken;                $wxuser['auth_refresh_token'] = $refreshToken;                $wxuser['auth_functions'] = json_encode($fcinfo['func_info']);                $wxuser['auth_business_info'] = json_encode($wxinfo['business_info']);                $wxuser['create_time'] = time();                if ($isExt) {                    $sign = $Wxuser->where($extFilter)->save($wxuser);                } else {                    $sign = $Wxuser->add($wxuser);                    if ($sign) {                        //添加功能模块                        $this->addfc($wxuser['token']);                           //记录公众号数量                        M('Users')->where(array('id' => $uid))->setInc('wechat_card_num');                    }                }                if ($sign) {                    redirect(C("site_url") . U('User/Index/index'));                }            }        }        $this->error("亲,获取授权信息失败!", U('User/Index/index'));

 

二. 全网发布

代码如下:

/**     * 公众号消息与事件接收URL     */    public function index() {        $timestamp = empty($_GET['timestamp']) ? '' : trim($_GET['timestamp']);        $nonce = empty($_GET['nonce']) ? '' : trim($_GET ['nonce']);        $msgSign = empty($_GET['msg_signature']) ? '' : trim($_GET['msg_signature']);        $signature = empty($_GET['signature']) ? '' : trim($_GET['signature']);        $encryptType = empty($_GET['encrypt_type']) ? '' : trim($_GET['encrypt_type']);        $openid = trim($_GET['openid']);                import("@.ORG.ArrayUtil");        import("@.ORG.Weixincrypt.WXBizMsgCrypt");        $input = file_get_contents('php://input');        $paramArr = ArrayUtil::xml2array($input);        //$this->logPrint($paramArr);        //$this->logPrint($_GET);        //解密        $wxData = C("platform_setting");        $encodingAesKey = $wxData['encodingAesKey'];        $token = $wxData['token'];        $appId = $wxData['appId'];        $Wxcrypt = new WXBizMsgCrypt($token, $encodingAesKey, $appId);        $format = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%s]]></Encrypt></xml>";        $fromXml = sprintf($format, $paramArr['Encrypt']);        $errCode = $Wxcrypt->decryptMsg($msgSign, $timestamp, $nonce, $fromXml, $toXml); // 解密        $this->logPrint($toXml);        if ($errCode == 0) {            $param = ArrayUtil::xml2array($toXml);            $keyword = isset($param['Content']) ? trim($param['Content']) : '';            // 案例1 - 发送事件            if (isset($param['Event']) && $paramArr['ToUserName'] == 'gh_3c884a361561') {                $contentStr = $param ['Event'] . 'from_callback';            }            // 案例2 - 返回普通文本            elseif ($keyword == "TESTCOMPONENT_MSG_TYPE_TEXT") {                $contentStr = "TESTCOMPONENT_MSG_TYPE_TEXT_callback";            }            // 案例3 - 返回Api文本信息            elseif (strpos($keyword, "QUERY_AUTH_CODE:") !== false) {                import("@.ORG.HttpTool");                $authcode = str_replace("QUERY_AUTH_CODE:", "", $keyword);                $contentStr = $authcode . "_from_api";                $HT = new HttpTool();                $authDetail = $HT->getAccessTokenByAuthCode($authcode);                $accessToken = $authDetail['authorizer_access_token'];                $HT->sendFansText($accessToken, $param['FromUserName'], $contentStr);                //$tokenInfo = WechatOpenApiLogic::getAuthorizerAccessTokenByAuthCode($ticket);                //$param ['authorizerAccessToken'] = $tokenInfo ['authorization_info'] ['authorizer_access_token'];                //self::sendServiceMsg($param['FromUserName'], $param['ToUserName'], 1, $contentStr); // 客服消息接口                return 1;            }            $result = '';            if (!empty($contentStr)) {                $xmlTpl = "<xml>            <ToUserName><![CDATA[%s]]></ToUserName>            <FromUserName><![CDATA[%s]]></FromUserName>            <CreateTime>%s</CreateTime>            <MsgType><![CDATA[text]]></MsgType>            <Content><![CDATA[%s]]></Content>            </xml>";                $result = sprintf($xmlTpl, $param['FromUserName'], $param['ToUserName'], time(), $contentStr);                if (isset($_GET['encrypt_type']) && $_GET['encrypt_type'] == 'aes') { // 密文传输                    $wxData = C("platform_setting");                    $msgCryptObj = new WXBizMsgCrypt($wxData['token'], $wxData['encodingAesKey'], $wxData['appId']);                    $encryptMsg = '';                    $msgCryptObj->encryptMsg($result, $_GET['timestamp'], $_GET['nonce'], $encryptMsg);                    $result = $encryptMsg;                }            }            echo $result;        }    }

 

阅读全文
1 0
原创粉丝点击