微信開發(fā)接入指南
概述
接入微信公眾平臺開發(fā),開發(fā)者需要按照如下步驟完成:
1、填寫服務器配置
2、驗證服務器地址的有效性
3、依據(jù)接口文檔實現(xiàn)業(yè)務邏輯
下面詳細介紹這3個步驟。
***步:填寫服務器配置
登錄微信公眾平臺官網(wǎng)后,在公眾平臺后臺管理頁面 - 開發(fā)者中心頁,點擊“修改配置”按鈕,填寫服務器地址(URL)、Token和EncodingAESKey,其中URL是開發(fā)者用來接收微信消息和事件的接口URL。Token可由開發(fā)者可以任意填寫,用作生成簽名(該Token會和接口URL中包含的Token進行比對,從而驗證安全性)。EncodingAESKey由開發(fā)者手動填寫或隨機生成,將用作消息體加解密密鑰。
同時,開發(fā)者可選擇消息加解密方式:明文模式、兼容模式和安全模式。模式的選擇與服務器配置在提交后都會立即生效,請開發(fā)者謹慎填寫及選擇。加解密方式的默認狀態(tài)為明文模式,選擇兼容模式和安全模式需要提前配置好相關加解密代碼,詳情請參考消息體簽名及加解密部分的文檔。
第二步:驗證服務器地址的有效性
開發(fā)者提交信息后,微信服務器將發(fā)送GET請求到填寫的服務器地址URL上,GET請求攜帶四個參數(shù):
開發(fā)者通過檢驗signature對請求進行校驗(下面有校驗方式)。若確認此次GET請求來自微信服務器,請原樣返回echostr參數(shù)內(nèi)容,則接入生效,成為開發(fā)者成功,否則接入失敗。
加密/校驗流程如下:
1. 將token、timestamp、nonce三個參數(shù)進行字典序排序
2. 將三個參數(shù)字符串拼接成一個字符串進行sha1加密
3. 開發(fā)者獲得加密后的字符串可與signature對比,標識該請求來源于微信
檢驗signature的PHP示例代碼:
- private function checkSignature()
- {
- $signature = $_GET["signature"];
- $timestamp = $_GET["timestamp"];
- $nonce = $_GET["nonce"];
- $token = TOKEN;
- $tmpArr = array($token, $timestamp, $nonce);
- sort($tmpArr, SORT_STRING);
- $tmpStr = implode( $tmpArr );
- $tmpStr = sha1( $tmpStr );
- if( $tmpStr == $signature ){
- return true;
- }else{
- return false;
- }
- }
PHP示例代碼
- <?php
- /**
- * wechat php test
- */
- //define your token
- define("TOKEN", "weixin");
- $wechatObj = new wechatCallbackapiTest();
- $wechatObj->valid();
- class wechatCallbackapiTest
- {
- public function valid()
- {
- $echoStr = $_GET["echostr"];
- //valid signature , option
- if($this->checkSignature()){
- echo $echoStr;
- exit;
- }
- }
- public function responseMsg()
- {
- //get post data, May be due to the different environments
- $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
- //extract post data
- if (!emptyempty($postStr)){
- /* libxml_disable_entity_loader is to prevent XML eXternal Entity Injection,
- the best way is to check the validity of xml by yourself */
- libxml_disable_entity_loader(true);
- $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
- $fromUsername = $postObj->FromUserName;
- $toUsername = $postObj->ToUserName;
- $keyword = trim($postObj->Content);
- $time = time();
- $textTpl = "<xml>
- <ToUserName><![CDATA[%s]]></ToUserName>
- <FromUserName><![CDATA[%s]]></FromUserName>
- <CreateTime>%s</CreateTime>
- <MsgType><![CDATA[%s]]></MsgType>
- <Content><![CDATA[%s]]></Content>
- <FuncFlag>0</FuncFlag>
- </xml>";
- if(!emptyempty( $keyword ))
- {
- $msgType = "text";
- $contentStr = "Welcome to wechat world!";
- $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
- echo $resultStr;
- }else{
- echo "Input something...";
- }
- }else {
- echo "";
- exit;
- }
- }
- private function checkSignature()
- {
- // you must define TOKEN by yourself
- if (!defined("TOKEN")) {
- throw new Exception('TOKEN is not defined!');
- }
- $signature = $_GET["signature"];
- $timestamp = $_GET["timestamp"];
- $nonce = $_GET["nonce"];
- $token = TOKEN;
- $tmpArr = array($token, $timestamp, $nonce);
- // use SORT_STRING rule
- sort($tmpArr, SORT_STRING);
- $tmpStr = implode( $tmpArr );
- $tmpStr = sha1( $tmpStr );
- if( $tmpStr == $signature ){
- return true;
- }else{
- return false;
- }
- }
- }
- ?>
第三步:依據(jù)接口文檔實現(xiàn)業(yè)務邏輯
驗證URL有效性成功后即接入生效,成為開發(fā)者。如果公眾號類型為服務號(訂閱號只能使用普通消息接口),可以在公眾平臺網(wǎng)站中申請認證,認證成功的服務號將獲得眾多接口權限,以滿足開發(fā)者需求。
此后用戶每次向公眾號發(fā)送消息、或者產(chǎn)生自定義菜單點擊事件時,開發(fā)者填寫的服務器配置URL將得到微信服務器推送過來的消息和事件,然后開發(fā)者可以依據(jù)自身業(yè)務邏輯進行響應,例如回復消息等。
公眾號調(diào)用各接口時,一般會獲得正確的結果,具體結果可見對應接口的說明。返回錯誤時,可根據(jù)返回碼來查詢錯誤原因。全局返回碼說明
用戶向公眾號發(fā)送消息時,公眾號方收到的消息發(fā)送者是一個OpenID,是使用用戶微信號加密后的結果,每個用戶對每個公眾號有一個***的OpenID。
此外,由于開發(fā)者經(jīng)常有需在多個平臺(移動應用、網(wǎng)站、公眾帳號)之間共通用戶帳號,統(tǒng)一帳號體系的需求,微信開放平臺(open.weixin.qq.com)提供了UnionID機制。開發(fā)者可通過OpenID來獲取用戶基本信息,而如果開發(fā)者擁有多個應用(移動應用、網(wǎng)站應用和公眾帳號,公眾帳號只有在被綁定到微信開放平臺帳號下后,才會獲取UnionID),可通過獲取用戶基本信息中的UnionID來區(qū)分用戶的***性,因為只要是同一個微信開放平臺帳號下的移動應用、網(wǎng)站應用和公眾帳號,用戶的UnionID是***的。換句話說,同一用戶,對同一個微信開放平臺帳號下的不同應用,UnionID是相同的。詳情請在微信開放平臺的資源中心-移動應用開發(fā)-微信登錄-授權關系接口調(diào)用指引-獲取用戶個人信息(UnionID機制)中查看。
另請注意,微信公眾號接口只支持80接口。