我使用自定义代码连接到Twitter并请求访问令牌。出于某种原因,当试图发布到" access_token"在API上它返回"无效或过期的令牌"。代码如下(除了一些外部函数调用和属性,这应该足以复制错误):
public function authenticate($get,$return = false) {
session_start();
if (!isset($get['oauth_verifier'])){
// Step 1 - get a request token
$step1 = $this->processRequest('oauth/request_token',0,$this->pObj->getRedirectUrl().'?process=true');
parse_str($step1,$parts);
if ($parts['oauth_callback_confirmed'] !== 'true'){ die('Error with process'); }
$_SESSION['tw_secret'] = $parts['oauth_token_secret'];
// Step 2
$url = str_replace('1.1/','',$this->api_url);
header("Location: {$url}oauth/authenticate?oauth_token={$parts['oauth_token']}");
} else {
// Step 3
$this->o_token = $get['oauth_token'];
$this->o_secret = $_SESSION['tw_secret'];
$content['oauth_verifier'] = $get['oauth_verifier'];
$step3 = $this->processRequest('oauth/access_token',1,null,$content,'array');
}
}
// https://dev.twitter.com/docs/auth/creating-signature
private function generateSignature($oauth,$fullurl,$http_method,$content){
// Take params from url
$main_url = explode('?',$fullurl);
// Split the content
$contents = explode('&',$content);
$urls = array_merge(explode('&',$main_url[1]),$contents);
foreach ($urls as $param){
$bits = explode('=',$param);
if (strlen($bits[0])){
$oauth[$bits[0]] = rawurlencode($bits[1]);
}
}
ksort($oauth);
$string = http_build_query($oauth);
$new_string = strtoupper($http_method).'&'.urlencode($main_url[0]).'&'.urlencode(urldecode($string));
// The request_token request doesn't need a o_secret because it doesn't have one!
$sign_key = strstr($fullurl,'request_token') ? $this->c_secret.'&' : $this->c_secret.'&'.$this->o_secret;
return urlencode(base64_encode(hash_hmac('sha1',$new_string,$sign_key,true)));
}
public function processRequest($in_url,$test = false,$callback = null,$content = null, $content_type = 'json',$form_content_type = 'application/x-www-form-urlencoded'){
$method = 'GET';
// Twitter still uses Oauth1 (which is a pain)
$oauth = array(
'oauth_consumer_key'=>$this->c_key,
'oauth_nonce'=>$this->random(32),
'oauth_signature_method'=>'HMAC-SHA1',
'oauth_timestamp'=>time(),
'oauth_token'=>$this->o_token,
'oauth_version'=>'1.0'
);
$url = $this->api_url.$in_url;
if (strlen($callback)){
$oauth['oauth_callback'] = urlencode(urldecode($callback));
unset($oauth['oauth_token']);
$method = 'POST';
$url = str_replace('1.1/','',$url);
}
if (is_array($content) || strlen($content)){ $method = 'POST'; }
$oauth['oauth_signature'] = $this->generateSignature($oauth,$url,$method,'');
ksort($oauth);
foreach ($oauth as $k=>$v){
$auths[] = $k.'="'.$v.'"';
}
$stream = array('http' =>
array(
'method' => $method,
'ignore_errors'=>true, // http://php.net/manual/en/context.http.php - otherwise browser returns error not error content
'follow_location'=>false,
'max_redirects'=>0,
'header'=> array(
'Content-type: '.$form_content_type,
'Authorization: OAuth '.implode(', ',$auths),
'Connection: close'
)
)
);
if (is_array($content)){
$content = $content_type == 'json' ? json_encode($content) : http_build_query($content);
/* foreach ($content as $k=>$v){
$strs[] = "$k=".urlencode(urldecode($v));
}
// Just for now to keep things simple
$content = 'status=Hello%20Ladies%20%2b%20Gentlemen%2c%20a%20signed%20OAuth%20request%21';*/
}
if (!is_null($content)){
$stream['http']['content'] = $content;
}
// Tell streams to make a request
// Invalid key or 401 error tends to suggest an incorrect signing key / signature
$response = file_get_contents($url, false, stream_context_create($stream));
if ($test){
print'<pre>';print_r($oauth);print'</pre>';
print'<pre>';print_r($stream);print'</pre>';
//echo $callback.'<br>';
echo $url.'<br>';
//print'<pre>';print_r($http_response_header);print'</pre>';
print'<pre>[';print_r($response);print']</pre>';
}
if (!is_object(json_decode($response))){
// Content supplied is not json - just return it
return $response;
} else {
$response = json_decode($response);
}
return $this->pObj->convertObjectToArray($response);
}
答案 0 :(得分:0)
问题的原因是:
1)不应包含Twitter API的版本 2)帖子缺少签名中的Oauth_verifier
感谢twitteroauth提供了一些指导。