另一个失败的 twitter oAuth cURL 访问令牌请求
Posted
技术标签:
【中文标题】另一个失败的 twitter oAuth cURL 访问令牌请求【英文标题】:another twitter oAuth cURL access token request that fails 【发布时间】:2011-03-18 18:01:24 【问题描述】:以下函数给出验证错误而不是令牌:
无法验证 oAuth 签名和令牌
function request_token()
// Set url
$url = $this->site.$this->request_token_path; // http://api.twitter.com/oauth/request_token
// Params to pass to twitter and create signature
$params['oauth_consumer_key'] = $this->consumerKey;
$params['oauth_token'] = '';
$params['oauth_nonce'] = SHA1(time());
$params['oauth_timestamp'] = time();
$params['oauth_signature_method'] = $this->signatureMethod; // HMAC-SHA1;
$params['oauth_version'] = $this->version; // 1.0
ksort($params);
//print "<pre>"; print_r($params); print "</pre>";
// Create Signature
$concatenatedParams = '';
foreach($params as $k => $v)
$concatenatedParams .= "$k=$v&";
$concatenatedParams = substr($concatenatedParams,0,-1);
$signatureBaseString = "POST&".urlencode($url)."&".urlencode($concatenatedParams);
$params['oauth_signature'] = base64_encode(hash_hmac('SHA1', $signatureBaseString, $this->secret."&", TRUE));
// Do cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLINFO_HEADER_OUT, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
$exec = curl_exec ($ch);
$info = curl_getinfo($ch);
curl_close ($ch);
print $exec;
//print "<pre>"; print_r($info); print "</pre>";
【问题讨论】:
请注意。 Twitter 存在 oAuth 问题。这可能不是你的问题。 dev.twitter.com/status 谢谢 - 我不认为它... 【参考方案1】:以下是我到目前为止汇总的内容:-)
class Twitauth
var $key = '';
var $secret = '';
var $request_token = "https://twitter.com/oauth/request_token";
function Twitauth($config)
$this->key = $config['key']; // consumer key from twitter
$this->secret = $config['secret']; // secret from twitter
function getRequestToken()
// Default params
$params = array(
"oauth_version" => "1.0",
"oauth_nonce" => time(),
"oauth_timestamp" => time(),
"oauth_consumer_key" => $this->key,
"oauth_signature_method" => "HMAC-SHA1"
);
// BUILD SIGNATURE
// encode params keys, values, join and then sort.
$keys = $this->_urlencode_rfc3986(array_keys($params));
$values = $this->_urlencode_rfc3986(array_values($params));
$params = array_combine($keys, $values);
uksort($params, 'strcmp');
// convert params to string
foreach ($params as $k => $v) $pairs[] = $this->_urlencode_rfc3986($k).'='.$this->_urlencode_rfc3986($v);
$concatenatedParams = implode('&', $pairs);
// form base string (first key)
$baseString= "GET&".$this->_urlencode_rfc3986($this->request_token)."&".$this->_urlencode_rfc3986($concatenatedParams);
// form secret (second key)
$secret = $this->_urlencode_rfc3986($this->secret)."&";
// make signature and append to params
$params['oauth_signature'] = $this->_urlencode_rfc3986(base64_encode(hash_hmac('sha1', $baseString, $secret, TRUE)));
// BUILD URL
// Resort
uksort($params, 'strcmp');
// convert params to string
foreach ($params as $k => $v) $urlPairs[] = $k."=".$v;
$concatenatedUrlParams = implode('&', $urlPairs);
// form url
$url = $this->request_token."?".$concatenatedUrlParams;
// Send to cURL
print $this->_http($url);
function _http($url, $post_data = null)
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
if(isset($post_data))
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$response = curl_exec($ch);
$this->http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$this->last_api_call = $url;
curl_close($ch);
return $response;
function _urlencode_rfc3986($input)
if (is_array($input))
return array_map(array('Twitauth', '_urlencode_rfc3986'), $input);
else if (is_scalar($input))
return str_replace('+',' ',str_replace('%7E', '~', rawurlencode($input)));
else
return '';
【讨论】:
不错!它有效,在 getRequestToken 方法的末尾有一个“打印”而不是“返回”。 我正试图让这个东西在 C#(不懂 php)中工作,所以我有点困惑。是 var $secret,来自 twitter 的秘密消费者密钥吗? 我有点晚了,if (is_array($input)) return array_map(array('Twitauth', '_urlencode_rfc3986'), $input);
有什么意义
这不起作用,除非您按照***.com/a/4199002/389976 的附加说明进行操作
天哪!谢谢!我一直在寻找一个可以在不使用 cURL 的情况下使用的功能,我只是删除了 _http
函数中的所有内容并用 $response=file_get_contents($url)
替换它,令我惊讶的是,它起作用了!!【参考方案2】:
不确定您是否仍在研究此问题,或者它是否适合您,但我有类似的设置并且遇到了同样的问题。我最终发现我正在 urlencoding 一到多次。 尝试注释掉这部分:
$keys = $this->_urlencode_rfc3986(array_keys($params));
$values = $this->_urlencode_rfc3986(array_values($params));
$params = array_combine($keys, $values);
为我工作,所以也许会有所帮助。
【讨论】:
***.com/users/195192/good-bye 应该修改他的帖子,感谢您对他的回答的洞察力!【参考方案3】:我承认这不是一个真正的答案,但如果可以,请使用 PECL OAuth 包。 Rasmus Lerdorf wrote a tutorial on how to use it 它让我解决了同样的问题。
【讨论】:
【参考方案4】:我遇到了同样的问题,我缺少的是将标头传递给 curl 请求。如这个问题所示,我还发送了 $header = array('Expect:'),这就是我的问题。我开始在标头中发送带有其他数据的签名,如下所示,它为我解决了这个问题。
$header = calculateHeader($parameters, 'https://api.twitter.com/oauth/request_token');
function calculateHeader(array $parameters, $url)
// redefine
$url = (string) $url;
// divide into parts
$parts = parse_url($url);
// init var
$chunks = array();
// process queries
foreach($parameters as $key => $value) $chunks[] = str_replace('%25', '%', urlencode_rfc3986($key) . '="' . urlencode_rfc3986($value) . '"');
// build return
$return = 'Authorization: OAuth realm="' . $parts['scheme'] . '://' . $parts['host'] . $parts['path'] . '", ';
$return .= implode(',', $chunks);
// prepend name and OAuth part
return $return;
function urlencode_rfc3986($value)
if(is_array($value)) return array_map('urlencode_rfc3986', $value);
else
$search = array('+', ' ', '%7E', '%');
$replace = array('%20', '%20', '~', '%25');
return str_replace($search, $replace, urlencode($value));
【讨论】:
以上是关于另一个失败的 twitter oAuth cURL 访问令牌请求的主要内容,如果未能解决你的问题,请参考以下文章
PHP 如何在没有oAuth的情况下使用php和Curl更改Twitter的状态
通过 CURL 中的 Twitter Rest API 获取多个屏幕名称的最新推文
Swift Alamofire 上的 Django oauth2 令牌请求失败