微信token驗證失敗的幾種情況

王明輝發表於2018-03-22

最近在研究用PHP做微信開發的時候,“修改配置時”,總是遇到token驗證失敗的提示。歷經一番查詢,種種輸出日誌和echo,發現,如果不echo除錯資訊,也不寫日誌,就不需要ob_clean(),如果一旦啟用了輸出或者寫日誌檔案,那麼在最後的echo結果前,一定要呼叫ob_clean(),否則就會呼叫失敗。

經測試,以下三種情況都會遇到相同的問題。

真想知道,如果使用了輸出緩衝而不用ob_clean()清理的話,騰訊那邊接收到的東西是什麼,為什麼會導致失敗。

 

情況一:

<?php
      //$file  = 'log.txt';//要寫入檔案的檔名(可以是任意檔名),如果檔案不存在,將會建立一個
      
      //file_put_contents($file, "---開始日誌---" . PHP_EOL, FILE_APPEND);
      //file_put_contents($file, date('Y-m-d H:i:s',time()) . PHP_EOL, FILE_APPEND);      
    
      //$ip = $_SERVER["REMOTE_ADDR"];
      //file_put_contents($file, "ip:" . $ip . PHP_EOL,FILE_APPEND);
      //echo $ip;
      
      //$querystring = $_SERVER["QUERY_STRING"];
      //file_put_contents($file, "querystring:" . $querystring . PHP_EOL,FILE_APPEND);
      
      // 微信token認證
      
      $signature = $_GET["signature"];
      //file_put_contents($file, "signature:" . $signature . PHP_EOL,FILE_APPEND);
      
      $timestamp = $_GET["timestamp"];
      //file_put_contents($file,"timestamp:" . $timestamp . PHP_EOL,FILE_APPEND);
      
      $nonce = $_GET["nonce"];
      //file_put_contents($file, "nonce:".$nonce . PHP_EOL,FILE_APPEND);
      
      $echoStr = $_GET["echostr"];
      //file_put_contents($file, "echostr:" . $echoStr . PHP_EOL,FILE_APPEND);
      
      // 你的設定Token
      $token = "sabre";
   

      // 1)將token、timestamp、nonce三個引數進行字典序排序
      $tmpArr = array($token,$timestamp,$nonce);
      sort($tmpArr);

      // 2)將三個引數字串拼接成一個字串進行sha1加密
      $str = implode($tmpArr);
      $sign = sha1($str);
      
      //file_put_contents($file, "sign:" . $sign . PHP_EOL,FILE_APPEND);
      //file_put_contents($file, "signature:" . $signature . PHP_EOL,FILE_APPEND);
      
     /*if($data = file_get_contents($file)){; // 這個函式支援版本(PHP 4 >= 4.3.0, PHP 5) 
      echo "寫入檔案的內容是:$data" . "\r\n";
     }    */        

      // 3)開發者獲得加密後的字串可與signature對比,標識該請求來源於微信
      //file_put_contents($file, "signature長度 :" . strlen($signature) . PHP_EOL,FILE_APPEND);
      //file_put_contents($file, "sign長度:" . strlen($sign) . PHP_EOL,FILE_APPEND);
      if ($sign == $signature) {
       //echo $echostr;
        //return true ;
        //ob_clean();
        //file_put_contents($file, "echoStr:" . $echoStr . PHP_EOL,FILE_APPEND);
        echo $echoStr;
      }
?>

情況二,不帶日誌,相對簡潔一些的

<?php
        //echo "測試頁面3";
      // 微信token認證
      $signature = $_GET["signature"];
      $timestamp = $_GET["timestamp"];
      $nonce = $_GET["nonce"];
      $echoStr = $_GET["echostr"];
      // 你的設定Token
          $token = "sabre";
      
          
      // 1)將token、timestamp、nonce三個引數進行字典序排序
      $tmpArr = array($token,$timestamp,$nonce);
      sort($tmpArr);

      // 2)將三個引數字串拼接成一個字串進行sha1加密
      $str = implode($tmpArr);
      $sign = sha1($str);

      // 3)開發者獲得加密後的字串可與signature對比,標識該請求來源於微信
      if ($sign == $signature) {
          //ob_clean();
        echo $echoStr;
      }
?>

情況三,方倍工作室的版本的簡化版,僅保留了token驗證部分

<?php
/*
    方倍工作室 http://www.cnblogs.com/txw1958/
    CopyRight 2013 www.doucube.com  All Rights Reserved
*/
//traceHttp();
echo "測試";
define("TOKEN", "sabre");
$wechatObj = new wechatCallbackapiTest();
 
    $wechatObj->valid();
 

class wechatCallbackapiTest
{
    public function valid()
    {
        $echoStr = $_GET["echostr"];
        if($this->checkSignature()){
            ob_clean();
            echo $echoStr;
            exit;
        }
    }

    private function checkSignature()
    {
        $signature = $_GET["signature"];
        $timestamp = $_GET["timestamp"];
        $nonce = $_GET["nonce"];

        $token = TOKEN;
        $tmpArr = array($token, $timestamp, $nonce);
        sort($tmpArr);
        $tmpStr = implode( $tmpArr );
        $tmpStr = sha1( $tmpStr );

        if( $tmpStr == $signature ){
            return true;
        }else{
            return false;
        }
    }
}


?>

 

相關文章