0

keek.com API、特に「検索キーク」機能 ( https://developers.keek.com/api/commands/search_keek ) を実装しようとしています。1 つの検索語に対してはすべて正常に機能しますが、2 つ以上の語句を検索語として使用しようとすると、「4006 署名が無効です」というエラーが表示されます。私が理解したように、これは、スペースまたはその他のアルファベット以外の文字の間違った URL エンコードが原因です。これは私のコードです。これは、1 単語のフレーズでは機能しますが、複数の単語のフレーズでは機能しません。

    $apiKey = Yii::app()->params['keek']['api_key'];
    $apiSecret = Yii::app()->params['keek']['api_secret'];
    $timestamp = time();

    $paramsArr = array(
        'auth_api' => $apiKey,
        'auth_timestamp' => $timestamp,
        'term' => $searchPhrase,         
        'number' => Yii::app()->params['keek']['keeks_per_page'],
    );

    // calculate min id (for pagination)
    if(isset($socialPageParam[Yii::app()->params['searchEngines']['enginesUrls']['keek']])
        && !empty($socialPageParam[Yii::app()->params['searchEngines']['enginesUrls']['keek']]))
    {
        $sinceId = min(
            $socialPageParam[Yii::app()->params['searchEngines']['enginesUrls']['keek']]
        );

        if($sinceId)
            $paramsArr['since_id'] = $sinceId;
    }         

    // sort alphabeticaly
    ksort($paramsArr);

    $paramsOfQueryStr = http_build_query($paramsArr);

    $paramsOfQueryStr = str_replace(
        array('+', '%7E'), 
        array('%20', '~'), 
        $paramsOfQueryStr
    );


    $urlEncodedRequest = rawurlencode($paramsOfQueryStr);

    $apiUrl = Yii::app()->params['keek']['api_search_keeks_url'];

    $initalAPIurl = rawurlencode($apiUrl);

    // forming signature base
    $signatureBase = 'GET&' . $initalAPIurl . '&' .  $urlEncodedRequest;

    // forming signing token
    $signingToken = $apiKey . '&' . $timestamp . '&' . $apiSecret;

    // forming signature as hashed by sha1 string in binary
    $signature = base64_encode(hash_hmac('sha1', $signatureBase, $signingToken, true));

    // add signature to headers
    $headersArr = array(
        "API: $apiKey",
        "Timestamp: $timestamp",
        "Signature: $signature",                
    );

    // forming full url to call
    $fullUrl = $apiUrl . '?' . $paramsOfQueryStr;

    // make call to keek's API
    $apiRes = Yii::app()->utils->curlGetContent($fullUrl, $headersArr);                   

    var_dump($apiRes);die;

この問題を解決する方法を知っていれば、私を助けてください。前もって感謝します。

4

1 に答える 1

0

私はそれを理解しました。現在、このコードの 2 つの作業バージョンがあります。1 つは js で、もう 1 つは php です。

js:

var timestamp = Math.round(new Date().getTime() / 1000);
var api = '(your api)';
var secret = '(your secret)';

var theUrl = "http://api.keek.com/v/1/keek/search?term="+encodeURIComponent("message me");
var parameterString = "auth_api=" + encodeURIComponent(api) + "&auth_timestamp=" + encodeURIComponent(timestamp) + "&term=" + encodeURIComponent(encodeURIComponent("message me"));
console.log("PARAMSTRING: "+parameterString);
var signatureBaseString = "GET&" + encodeURIComponent("http://api.keek.com/v/1/keek/search") + "&" + encodeURIComponent(parameterString);
console.log("SIGBASE: "+signatureBaseString);

var signingToken = api + "&" + timestamp + "&" + secret;

var hash = CryptoJS.HmacSHA1(signatureBaseString, signingToken);

var signature = hash.toString(CryptoJS.enc.Base64);

console.log('cmd: ','curl -v -H "API:'+api+'" -H "Timestamp:'+timestamp+'" -H "Signature:'+signature+'" '+ theUrl);

var thisCode = 'curl -v -H "API:'+api+'" -H "Timestamp:'+timestamp+'" -H "Signature:'+signature+'" '+ theUrl;


window.onload = function() {
output = document.getElementById("output");
output.value = thisCode;
};

PHP:

    $apiKey = 'api key here';
    $apiSecret = 'api secret here';
    $timestamp = time();

    $searchStr = Yii::app()->utils->encodeURIComponent('usa today');

    $data = array(
        'auth_api'=>'1e8b017d015d690a69a487995339561ed7d8cce7',
        'auth_timestamp'=>$timestamp,
        'term' => $searchStr,
    );

    ksort($data);

    $urlEncodedRequest = '';

    foreach($data as $paramName => $paramVal)
    {
        $urlEncodedRequest .= "&$paramName=" . Yii::app()->utils->encodeURIComponent($paramVal);
    }

    $urlEncodedRequest = substr($urlEncodedRequest, 1, strlen($urlEncodedRequest));        
    $urlEncodedRequest = Yii::app()->utils->encodeURIComponent($urlEncodedRequest);

    $url = 'http://api.keek.com/v/1/user/search?term=' . $searchStr;

    $initalAPIurl = Yii::app()->utils->encodeURIComponent('http://api.keek.com/v/1/user/search');

    $signatureBase = 'GET&' . $initalAPIurl . '&' .  $urlEncodedRequest;

    $signingToken = $apiKey . '&' . $timestamp . '&' . $apiSecret;
    $signature = base64_encode(hash_hmac('sha1', $signatureBase, $signingToken, true));

    $headersArr = array(
        "API: $apiKey",
        "Timestamp: $timestamp",
        "Signature: $signature",                
    );

    var_dump(Yii::app()->utils->curlGetContent($url, $headersArr));   

エラーは php rawurlencode() 関数にありました。代わりに、js の encodeURIComponent() 関数の php アナログを使用しました。

function encodeURIComponent($str) 
{
    $revert = array('%21'=>'!', '%2A'=>'*', '%27'=>"'", '%28'=>'(', '%29'=>')');
    return strtr(rawurlencode($str), $revert);
}

また、検索フレーズ (最初の例では $searchPhrase) を 2 回エンコードする必要があります。今はすべて正常に動作します。keek api の実装をお楽しみください。

于 2013-09-18T11:41:49.133 に答える