本系統教程以微信公衆平台應用天氣神(賬号WeatherGod,支援國内近400個城市天氣的名稱、拼音、區号、郵編以及語音觸發模式查詢)為例,講解微信接口開發過程。歡迎大家關注該賬号并使用語音方式查詢當地天氣,二維碼見底部。
本文是微信公衆平台消息接口開發(1)啟用接口 的下部分
三、伺服器沒有響應Token驗證的解決方法
1. 技術分析法
這次我們在代碼裡面加入跟蹤http記錄的方法來檢視我們自己的伺服器收到了請求沒有回應,還是微信根本沒有發請求過來。
通過調用系統環境變量$_SERVER,可以檢視到HTTP請求的資訊,其中兩項重要的是
$_SERVER["REMOTE_ADDR"] //記錄來訪者的IP,我們記錄微信伺服器是否通路過$_SERVER["QUERY_STRING"] //查詢請求字元串
把其加入代上面的代碼中,并且将其寫入到本地檔案中來,全部代碼如下:
<?phpdefine("TOKEN", "天氣神");date_default_timezone_set('Asia/Hong_Kong'); traceHttp();$wechatObj = new wechatCallbackapiTest();$wechatObj->valid();class wechatCallbackapiTest{ public function valid() { $echoStr = $_GET["echostr"]; //随機字元串 if($this->checkSignature()){ echo $echoStr; exit; } } private function checkSignature() { $signature = $_GET["signature"]; //微信加密簽名 $timestamp = $_GET["timestamp"]; //時間戳 $nonce = $_GET["nonce"]; //随機數 $token = TOKEN; $tmpArr = array($token, $timestamp, $nonce); sort($tmpArr); //sha1加密後與簽名對比 if( sha1(implode($tmpArr)) == $signature ){ return true; }else{ return false; } }}function traceHttp(){ logger(""); logger("REMOTE_ADDR:".$_SERVER["REMOTE_ADDR"].((strpos($_SERVER["REMOTE_ADDR"], "101.226"))?" From WeiXin":" Unknown IP")); logger("QUERY_STRING:".$_SERVER["QUERY_STRING"]);}function logger($content){ file_put_contents("log.html", date('Y-m-d H:i:s ').$content."<br>", FILE_APPEND);}?>
這樣,當我們送出之後,就會生成一個log.html檔案在目前目錄
用浏覽器直接打開填寫的url,也會寫一次檔案。
直接用浏覽器打開url+log.html路徑,我的記錄如下:
2013-01-30 10:15:18 2013-01-30 10:15:18 REMOTE_ADDR:212.179.24.103 Unknown IP2013-01-30 10:15:18 QUERY_STRING:
在微信中點選送出一次,再一次生成記錄,如下:
2013-01-30 10:15:49 2013-01-30 10:15:49 REMOTE_ADDR:101.226.89.83 From WeiXin2013-01-30 10:15:49 QUERY_STRING:signature=eded789463180edf6c13691398d0cb4c85fb0e23&echostr=5838479218127813673×tamp=1359100969&nonce=1359376876
從上可以看到,這次IP來自101.226.89.83,是微信的IP,我把這個IP加入到代碼中自行判斷了
另外它的查詢請求和官方指南中描述的一緻,是以可以确定,微信把消息送出到伺服器中了。送出應該成功。如果不成功,原因在于自己這邊。
2. 萬能成功法
如果你用上面的白方法還沒送出成功,被接口啟用問題已經折騰了N次,心灰意冷,打算退出微信接口開發,那你一定要再多看一眼下面的萬能方法。
再看一下驗證部分的源代碼
$wechatObj = new wechatCallbackapiTest();$wechatObj->valid();class wechatCallbackapiTest{ public function valid() { $echoStr = $_GET["echostr"]; //随機字元串 if($this->checkSignature()){ echo $echoStr; exit; } }
其實就調用一下valid()函數,在valid()函函數中檢查簽名,如果簽名成功,就應答echoStr。
如果我們跳過這個簽名呢......
public function valid() { $echoStr = $_GET["echostr"]; if(true){ echo $echoStr; exit; } }
經過試驗,送出也成功。證明也是可行的。但是。。。。
好像,這後面存在着微信一個很大的漏洞,很大很大,可能是無窮大!!!