one.
Authorization process
1. Receive component_verify_ticket:
[1] The WeChat server will push component_verify_ticket to the third-party message receiving address every 10 minutes, and it needs to be stored locally after getting it;
[2] The message of the WeChat third-party platform is encrypted (below), and it needs to be decrypted to obtain the required information;
[3] Receive and decrypt the message, the code is as follows:
/** * Authorization event receiving 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']); //The third party receives the message sent by the official account platform $msg = ''; $errCode = $Wxcrypt->decryptMsg($msgSign, $timestamp, $nonce, $fromXml, $msg); // 解密 if ($errCode == 0) { $param = ArrayTool::xml2array($msg); switch ($param['InfoType']) { case 'component_verify_ticket' : // authorization ticket $componentVerifyTicket = $param['ComponentVerifyTicket']; S('component_verify_ticket_' . $appId, $componentVerifyTicket); break; case 'unauthorized' : // cancel authorization break; case 'authorized' : // authorized break; case 'updateauthorized' : // update authorization break; } } exit("success"); }
2. Get component_access_token:
[1] Each token has a validity period (2 hours), and the call of the token is not unlimited. Please manage the token well by the third-party platform. When the token is about to expire (for example, 1 hour and 50 minutes) Refresh. So to cache component_access_token locally, the code is as follows:
$wxData = C("setting"); //1. Get component_verify_ticket $vt = S('component_verify_ticket_' . $wxData['appId']); $at = S('component_access_token_' . $wxData['appId']); //2. Get third-party platform 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); //cache 1 hour 50 minutes = 6600 seconds } else { return false; } }
3. Get pre_auth_code (note that this is a pre-authorization code, not an authorization code):
$wxData = C('platform_setting'); $ appId = $ wxData ['appId']; $HT = new HttpTool(); $at = $HT->getComponentAccessToken(); if ($at) { //3. Get the pre-authorization code 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("Dear, authorization failed!");
4. Use the authorization code to exchange the API call credentials and authorization information of the official account:
//1. Use the authorization code to exchange the API call credentials and authorization information of the official account 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. Obtain the basic information of the authorized party's official account $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"); // does it already exist $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']; //Wechat type authorizer official account type, 0 represents the subscription number, 1 represents the subscription number upgraded from the old historical account, and 2 represents service number $wxuser['weixin'] = $wxinfo['alias']; //WeChat $wxuser['headerpic'] = $wxinfo['head_img']; //Head $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) { //add function module $this->addfc($wxuser['token']); //Record the number of public accounts M('Users')->where(array('id' => $uid))->setInc('wechat_card_num'); } } if ($sign) { redirect(C("site_url") . U('User/Index/index')); } } } $this->error("Pro, failed to obtain authorization information!", U('User/Index/index'));
2. Publishing on the whole network
code show as below:
/** * Official account message and event receiving 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); // decrypt $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']) : ''; // case 1 - send event if (isset($param['Event']) && $paramArr['ToUserName'] == 'gh_3c884a361561') { $contentStr = $param ['Event'] . 'from_callback'; } // case 2 - return normal text elseif ($keyword == "TESTCOMPONENT_MSG_TYPE_TEXT") { $contentStr = "TESTCOMPONENT_MSG_TYPE_TEXT_callback"; } // Case 3 - return Api text information 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); // Customer service message interface 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; } }