简体   繁体   English

在PHP中签名Twitter Trend API v1.1请求失败

[英]Signing Twitter trends API v1.1 request in PHP fails

Since Twitter API version 1.1 every request has to be authenticated and signed via OAuth 1.0a. 从Twitter API版本1.1开始, 每个请求都必须通过OAuth 1.0a进行身份验证和签名。 In my PHP project I want to make use of the Twitter trends API, especially I want to use the GET trends/place call. 在我的PHP项目中,我想使用Twitter Trends API,尤其是我想使用GET Trends / place调用。 So it's read-only. 因此它是只读的。 Now, to authorize a request there's an excellent Twitter API documentation here . 现在,授权有一个很好的Twitter的API文档的请求在这里 We learn that we have to send an additional header in the HTTP request, called "Authorization" that contains a string starting with "OAuth " and including seven parameters: 我们了解到,我们必须在HTTP请求中发送一个称为“ Authorization”的附加标头,其中包含一个以“ OAuth”开头的字符串,并包含七个参数:

  1. oauth_consumer_key oauth_consumer_key
  2. oauth_nonce oauth_nonce
  3. oauth_signature oauth_signature
  4. oauth_signature_method oauth_signature_method
  5. oauth_timestamp oauth_timestamp
  6. oauth_token 组oauth_token
  7. oauth_version oauth_version

Of those seven parameters the above mentioned third one, oauth_signature, is kind of special because to build its value you have to include all the other parameters plus more and then sign it. 在这七个参数中,上面提到的第三个参数oauth_signature非常特殊,因为要构建其值,您必须包括所有其他参数以及更多参数,然后对其进行签名。 The process, again, is explained very well here . 同样, 这里对过程进行了很好的解释。

I implemented all these steps after registering my app and getting consumer key & secret and access token & secret. 注册我的应用程序并获取用户密钥和机密以及访问令牌和机密后,我执行了所有这些步骤。 Here's my PHP code (I crossed-out the secrets, of course): 这是我的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;

Problem is, the actual call to the API fails every time with an "HTTP/1.0 401 Unauthorized" error. 问题是,每次对API的实际调用都会失败,并显示“ HTTP / 1.0 401 Unauthorized”错误。 Can anyone tell my why and what I'm doing wrong here? 谁能告诉我为什么和我在做什么错? Thank you so much! 非常感谢!

Not sure if it's the same problem i have but try to check the timestamp mine was off exactly by 1 hour, go figure what that is!! 不知道这是否是我遇到的相同问题,但是尝试检查我的时间戳记是否恰好在1小时前关闭,请弄清楚那是什么!! daylite saving time 节省日光时间

Use this code 使用此代码

        $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);

I have Modified the code to get user timeline from this blog 我已修改代码以从此博客获取用户时间表

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM