Twitter API returns "Could not authenticate you" 如果 URL 中存在参数则出错

Twitter API returns "Could not authenticate you" error if parameters are present in URL

我正在尝试通过 OAuth 1.0a 加载 Twitter users friend 列表。 如果 URL 没有任何参数,它会起作用,例如:

作品:https://api.twitter.com/1.1/friends/list.json

无效:https://api.twitter.com/1.1/friends/list.json?cursor=-1&skip_status=true&include_user_entities=false

如果我向它添加参数,则会返回此错误:

Could not authenticate you

这可能是什么原因? 我的代码:

<?php
$oauthToken = 'removed'; 
$oauthTokenSecret = 'removed'; 

function buildBaseString($baseURI, $method, $params)
{
    $r = array(); 
    ksort($params); 
    foreach($params as $key=>$value){
        $r[] = "$key=" . rawurlencode($value); 
    }            

    return $method."&" . rawurlencode($baseURI) . '&' . rawurlencode(implode('&', $r));
}

function buildAuthorizationHeader($oauth)
{
    $r = 'Authorization: OAuth ';
    $values = array();
    foreach($oauth as $key=>$value)
        $values[] = "$key=\"" . rawurlencode($value) . "\""; 

    $r .= implode(', ', $values); 
    return $r; 
}

//WORKS:
$url = 'https://api.twitter.com/1.1/friends/list.json';

//DOESN'T WORK, WHY?:
//$url = 'https://api.twitter.com/1.1/friends/list.json?cursor=-1&skip_status=true&include_user_entities=false';

$consumer_key = 'removed';
$consumer_secret = 'removed';

$oauth = array( 'oauth_consumer_key' => $consumer_key,
                'oauth_nonce' => time(),
                'oauth_signature_method' => 'HMAC-SHA1',
                'oauth_token' => $oauthToken,
                'oauth_timestamp' => time(),
                'oauth_version' => '1.0');

$base_info = buildBaseString($url, 'GET', $oauth);

$composite_key = rawurlencode($consumer_secret) . '&' . rawurlencode($oauthTokenSecret);
$oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
$oauth['oauth_signature'] = $oauth_signature;


$header = array(buildAuthorizationHeader($oauth), 'Expect:');
$options = array( CURLOPT_HTTPHEADER => $header,
                  CURLOPT_HEADER => false,
                  CURLOPT_URL => $url,
                  CURLOPT_RETURNTRANSFER => true,
                  CURLOPT_SSL_VERIFYPEER => false);

$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);

echo "JSON: ".$json;

curl_close($feed);
?>

您似乎在 = 符号上使用了 rawurlencode。这会将其转换为 %3D.

所以当你想要 cursor=-1 时你会得到 cursor%3D-1

也许可以尝试简化函数,这样您就不会对 =?

进行编码

这是获取用户信息的示例代码

       require_once('oauth/twitteroauth.php'); 

$oauth_token='YOUR OAUTH TOKEN';
$oauth_token_secret='YOUR SECRET KEY';
function getConnectionWithAccessToken($oauth_token, $oauth_token_secret) {
  $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $oauth_token, $oauth_token_secret);
  return $connection;
}

$connection = getConnectionWithAccessToken($oauth_token, $oauth_token_secret);

$content = $connection->get('account/verify_credentials');

url 也有参数,所以你应该尝试遵循这个(在你的函数 buildBaseString 中):

  1. 将 HTTP 方法转换为大写并将输出字符串设置为该值。
  2. 将“&”字符附加到输出字符串。
  3. 百分比编码 URL 并将其附加到输出字符串。
  4. 将“&”字符附加到输出字符串。
  5. 百分比编码参数字符串并将其附加到输出 字符串。

(摘自:creating signatures

现在你有了类似这样的编码基础 url:

GET&https%3A%2F%2Fapi.twitter.com%2F1.1%2Ffriends%2Flist.json%3Fcursor%3D-1%26skip_status%3Dtrue%26include_user_entities%3Dfalse&oauth_consumer_key%3Dremoved%26oauth_nonce%3D1423633315%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1423633315%26oauth_token%3Dremoved%26oauth_version%3D1.0

也许你必须尝试得到这个:

GET&https%3A%2F%2Fapi.twitter.com%2F1.1%2Ffriends%2Flist.json&cursor%3D-1%26skip_status%3Dtrue%26include_user_entities%3Dfalse%26oauth_consumer_key%3Dremoved%26oauth_nonce%3D1423633315%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1423633315%26oauth_token%3Dremoved%26oauth_version%3D1.0

您需要在 OAuth headers 中包含您的参数。最好的方法是将它们从 URL.

中分离出来
$params = array(
    "cursor" => -1,
    "skip_status" => "true",
    "include_user_entities" => "false"
);

现在使用基础 url 构建基础字符串。

$url = 'https://api.twitter.com/1.1/friends/list.json'
$oAuthHeaders = $oauth + $params;
$base_info = buildBaseString($url, 'GET', $oAuthHeaders);
$composite_key = rawurlencode($consumer_secret) . '&' . rawurlencode($oauthTokenSecret);
$oauth_signature = base64_encode(hash_hmac('sha1', $base_info, $composite_key, true));
$oAuthHeaders['oauth_signature'] = $oauth_signature;

最后,使用附加参数创建URL字符串:

if ($params) {
   $finalURL = "$url?";
   foreach ($params as $key=>$param) {
       $finalURL .= rawurlencode($key) . "=" . rawurlencode($param) . "&";
   }
   $finalURL = substr($finalURL, 0, strlen($finalURL) - 1);
}

现在您可以寄出整个包裹了:

$header = array(buildAuthorizationHeader($oAuthHeaders), 'Expect:');