-1

I try to do wechat api integration. By putting the file in public folder it work. Here is my code

<?php
traceHttp();

define('TOKEN', 'xxxxx');
$wechatObj = new wechatCallbackapiTest();
if (isset($_GET['echostr'])) {
    $wechatObj->valid();
}else{
    $wechatObj->responseMsg();
}

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);
        $tmpStr = implode( $tmpArr );
        $tmpStr = sha1( $tmpStr );

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

    public function responseMsg(){  
        //get post data, May be due to the different environments  
        $postStr = file_get_contents('php://input');     

        //if (!empty($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);     


        switch($postObj->MsgType){              
             case "event":   
                $this->_doEvent($postObj);   
                break;  
             case "text":   
                $this->_doText($postObj);   
                break;  
             case "image":   
                $this->_doImage($postObj);   
                break;  
             case "voice":   
                $this->_doVoice($postObj);   
                break;  
             case "music":   
                $this->_doMusic($postObj);   
                break;  
            case "location":   
                $this->_doLocation($postObj);   
                break;  
             default:   
                break;  
        }    

    }

Now I want to create all this function inside a controller. But I get empty value for file_get_contents('php://input'). I even try to use $request->getContent() & $request->all() and both return empty value.

Anyone can advise me what is the problem? I'm been stuck to this problem for the whole day and I'm really appreciate any help. Thanks

Below is my laravel controller code:

public function authenticate(Request $request) {
    $token = 'xxxxxx';
    define("TOKEN", $token);
    if(isset($_GET['echostr'])) {
        $this->valid();
    } else {
        $content = $request->all();      
    }
}

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);
    $tmpStr = implode( $tmpArr );
    $tmpStr = sha1( $tmpStr );

    if($tmpStr == $signature){
        return true;
    } else {
        return false;
    }
}
etzzz
  • 165
  • 1
  • 4
  • 15
  • `$request->getContent()` should contain whatever is in `php://input` which you can parse. However if you misconfigured the webhook URL that causes a redirect (because your webserver enforces a trailing `/` or an https redirect) that data might get lost, so make sure WeChat has the correct and exact url it should call. If that is not the case, check out how some WeChat SDK packages handle it: https://packagist.org/?query=laravel%20wechat – Alex Aug 09 '18 at 12:38
  • mind to share why with the downvote? – etzzz Aug 10 '18 at 03:39
  • 1
    @AlexBouma Thanks I finally able to solve it. Refer to my answer. – etzzz Aug 10 '18 at 03:39

1 Answers1

1

Turn out for verification wechat api will use GET request but for sending msg will use POST request.

Since my route.php route is only Route::get, so my $request->getContent() return empty.

So instead of Route::get('/wechat-api', 'WController@verify');

I change to Route::any('/wechat-api', 'WController@verify');

After made the changes, $request->getContent() finally not empty anymore.

etzzz
  • 165
  • 1
  • 4
  • 15