在PHP中签署Twitter趋势API v1.1请求失败

时间:2013-01-28 11:09:19

标签: php oauth twitter twitter-oauth

由于Twitter API版本1.1 每个请求都必须通过OAuth 1.0a进行身份验证和签名。在我的PHP项目中,我想利用Twitter趋势API,特别是我想使用GET趋势/场所调用。所以它是只读的。 现在,为了授权请求,有一个很好的Twitter API文档here。我们了解到,我们必须在HTTP请求中发送一个额外的标头,称为“授权”,其中包含以“OAuth”开头并包含七个参数的字符串:

  1. oauth_consumer_key
  2. oauth_nonce
  3. oauth_signature
  4. oauth_signature_method
  5. oauth_timestamp
  6. 组oauth_token
  7. oauth_version
  8. 在上面提到的第三个参数oauth_signature中,有七个参数是特殊的,因为要构建它的值,你必须包括所有其他参数加上更多,然后签名。这个过程再次得到了很好的解释here

    我在注册我的应用并获取消费者密钥后,实施了所有这些步骤。秘密和访问令牌&秘密。这是我的PHP代码(当然我划掉了秘密):

        $HTTPmethod = 'GET';
    $twitterApiBaseUrl = 'https://api.twitter.com/1.1/trends/place.json';
    $twitterApiParams  = 'id=' . $WOEID;
    $twitterApiCallUrl = $twitterApiBaseUrl . '?' . $twitterApiParams;
    
    $OAuthConsumerKey = 'eV78fJOOiObfeytAwvWCg';
    $OAuthAccessToken = '1116971396-6uc4xOLziLAdiqOfrtKfuRraa2GdCzas9aQX8ZB';
    $OAConsumerSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
    $OATokenSecret    = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
    
    // building the necessary (as of Twitter API v1.1) authorization header
    // according to https://dev.twitter.com/docs/auth/authorizing-request
    $DST = 'OAuth ';
    
    // 1.: Consumer key
    $oaConsumerKeyKey = rawurlencode("oauth_consumer_key");
    $oaConsumerKeyVal = rawurlencode($OAuthConsumerKey);
    $DST .= $oaConsumerKeyKey . '="' . $oaConsumerKeyVal . '", ';
    
    // 2.: Nonce
    $oaNonceKey = rawurlencode("oauth_nonce");
    $oaNonceVal = rawurlencode(base64_encode(time()));
    $DST .= $oaNonceKey . '="' . $oaNonceVal . '", ';
    
    // 3.: Signature method
    $oaSignatureMethodKey = rawurlencode("oauth_signature_method");
    $oaSignatureMethodVal = rawurlencode('HMAC-SHA1');
    $DST .= $oaSignatureMethodKey . '="' . $oaSignatureMethodVal . '", ';
    
    // 4.: Timestamp
    $oaTimestampKey = rawurlencode("oauth_timestamp");
    $oaTimestampVal = rawurlencode(time());
    $DST .= $oaTimestampKey . '="' . $oaTimestampVal . '", ';
    
    // 5.: Token
    $oaTokenKey = rawurlencode("oauth_token");
    $oaTokenVal = rawurlencode($OAuthAccessToken);
    $DST .= $oaTokenKey . '="' . $oaTokenVal . '", ';
    
    // 6.: Version
    $oaVersionKey = rawurlencode("oauth_version");
    $oaVersionVal = rawurlencode('1.0');
    $DST .= $oaVersionKey . '="' . $oaVersionVal . '", ';
    
    // 7.: Signature
    // according to https://dev.twitter.com/docs/auth/creating-signature
    $preSignatureBaseString = $twitterApiParams;
    $preSignatureBaseString .= '&';
    $preSignatureBaseString .= $oaConsumerKeyKey . '=' . $oaConsumerKeyVal;
    $preSignatureBaseString .= '&';
    $preSignatureBaseString .= $oaNonceKey . '=' . $oaNonceVal;
    $preSignatureBaseString .= '&';
    $preSignatureBaseString .= $oaSignatureMethodKey . '=' . $oaSignatureMethodVal;
    $preSignatureBaseString .= '&';
        $preSignatureBaseString .= $oaTimestampKey . '=' . $oaTimestampVal;     
    $preSignatureBaseString .= '&';
    $preSignatureBaseString .= $oaTokenKey . '=' . $oaTokenVal;
    $preSignatureBaseString .= '&';
    $preSignatureBaseString .= $oaVersionKey . '=' .$oaVersionVal;
    
    print "<b>preSignatureBaseString:</b> $preSignatureBaseString<p/>\n";
    
    $signatureBaseString = $HTTPmethod;
    $signatureBaseString .= '&';
    $signatureBaseString .= rawurlencode($twitterApiBaseUrl);
    $signatureBaseString .= '&';
    $signatureBaseString .= rawurlencode($preSignatureBaseString);
    
    print "<b>signatureBaseString:</b> $signatureBaseString<p/>\n";
    
    $signingKey = rawurlencode($OAConsumerSecret) . '&' . rawurlencode($OATokenSecret);
    
    $oaSignatureKey = rawurlencode("oauth_signature");
    $oaSignatureVal = base64_encode(hash_hmac('sha1', $signatureBaseString, $signingKey));
    
    print "<b>oaSignatureVal:</b> $oaSignatureVal<p/>\n";
    
    $DST .= $oaSignatureKey . '="' . rawurlencode($oaSignatureVal) . '"';
    
    print "<b>DST:</b> $DST<p/>\n";
    
    $header = "User-Agent: MyCoolTwitterTrendsApp\r\n" .
              "Authorization: " . $DST . "\r\n";              
    $opts = array(
            'http' => array(
               'method'    => $HTTPmethod,
               'header'    => $header
            ));
    print "<b>header:</b> $header<p/>\n";
    
        $context = stream_context_create($opts);
    
    $twitterApiResponse = file_get_contents($twitterApiCallUrl, false, $context);
    
    $decodedResponse = json_decode($twitterApiResponse);
    
    echo $decodedResponse;
    

    问题是,每次使用“HTTP / 1.0 401 Unauthorized”错误时,对API的实际调用都会失败。任何人都可以告诉我为什么以及我在这里做错了什么? 非常感谢你!

2 个答案:

答案 0 :(得分:1)

不确定这是否与我有同样的问题,但是试着检查我的时间戳完全关闭1小时,去看看那是什么!! daylite节省时间

答案 1 :(得分:0)

使用此代码

        $oauth_hash = '';
        $oauth_hash .= 'oauth_consumer_key=YOUR_CONSUMER_KEY&';
        $oauth_hash .= 'oauth_nonce=' . time() . '&';
        $oauth_hash .= 'oauth_signature_method=HMAC-SHA1&';
        $oauth_hash .= 'oauth_timestamp=' . time() . '&';
        $oauth_hash .= 'oauth_token=YOUR_ACCESS_TOKEN&';
        $oauth_hash .= 'oauth_version=1.0';
        $base = '';
        $base .= 'GET';
        $base .= '&';
        $base .= rawurlencode('https://api.twitter.com/1.1/trends/place.json');
        $base .= '&';
        $base .= rawurlencode('id=23424848&'.$oauth_hash);
        $key = '';
        $key .= rawurlencode('YOUR_CONSUMER_SECRET');
        $key .= '&';
        $key .= rawurlencode('YOUR_ACCESS_TOKEN_SECRET');

        $signature = base64_encode(hash_hmac('sha1', $base, $key, true));
        $signature = rawurlencode($signature);
        $oauth_header = '';
        $oauth_header .= 'oauth_consumer_key="YOUR_CONSUMER_KEY", ';
        $oauth_header .= 'oauth_nonce="' . time() . '", ';
        $oauth_header .= 'oauth_signature="' . $signature . '", ';
        $oauth_header .= 'oauth_signature_method="HMAC-SHA1", ';
        $oauth_header .= 'oauth_timestamp="' . time() . '", ';
        $oauth_header .= 'oauth_token="YOUR_ACCESS_TOKEN", ';
        $oauth_header .= 'oauth_version="1.0", ';
        $curl_header = array("Authorization: Oauth {$oauth_header}", 'Expect:');
        $curl_request = curl_init();
        curl_setopt($curl_request, CURLOPT_HTTPHEADER, $curl_header);
        curl_setopt($curl_request, CURLOPT_HEADER, false);
        curl_setopt($curl_request, CURLOPT_URL, 'https://api.twitter.com/1.1/trends/place.json?id=23424848');
        curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, false);
        var_dump(curl_exec($curl_request));
        curl_close($curl_request);

我修改了代码以从this blog

获取用户时间线