2013-10-14 69 views
0

我试图实施“拍在与Twitter的”
我看到很多的问题,在这个话题在这里,我读过很多人并坚持所有
我用如下因素链接:叽叽喳喳的OAuth请求令牌失败

implementing Sign in with Twitter
POST oauth/request_token
Creating a signature
Authorizing a request

,其结果是
回应:无法验证的OAuth签名和令牌(可能这是最常见的错误=))

我做了什么:

date_default_timezone_set('UTC'); 
$oauth_consumer_key = 'mYOauThConsuMerKey'; //from app settings 

function generate_nonce() { 
    $mt = microtime(); 
    $rand = mt_rand(); 
    return md5($mt . $rand); // md5s look nicer than numbers 
} 
$oauth_nonce = generate_nonce(); 
    $http_method = 'POST'; 
    $base_url = 'https://api.twitter.com/oauth/request_token'; 
    $oauth_signature_method = 'HMAC-SHA1'; 
    $oauth_timestamp = time(); 
    $oauth_token = 'mytokenFromAPPsettoings'; 
    $oauth_version = '1.0'; 
$oauth_callback = 'http://twoends.home/backend'; 
    $params = array(
     rawurlencode('oauth_nonce')=>rawurlencode($oauth_nonce), 
     rawurlencode('oauth_callback')=>rawurlencode($oauth_callback), 
     rawurlencode('oauth_signature_method')=>rawurlencode($oauth_signature_method), 
     rawurlencode('oauth_timestamp')=>rawurlencode($oauth_timestamp), 
     rawurlencode('oauth_token')=>rawurlencode($oauth_token), 
     rawurlencode('oauth_version')=>rawurlencode($oauth_version), 
    ); 

    ksort($params); 
    $parameter_string = http_build_query($params,'','&'); 
     $base_string = strtoupper($http_method).'&'; 
     $base_string .= rawurlencode($base_url).'&'; 
     $base_string .= rawurlencode($parameter_string); 

     $oauth_consumer_secret = 'myappconsumersecret'; 
     $oauth_token_secret = 'mytokensecret'; 
$oauth_signing_key =rawurlencode($oauth_consumer_secret).'&'.rawurlencode($oauth_token_secret); 
$oauth_signature = base64_encode(hash_hmac('sha1', $base_string, $oauth_signing_key, true)); 
$DST ='OAuth '; 
foreach($params as $key=>$value){ 
    $DST .= $key.'='.'"'.$value.'"&'; 
} 
$DST = rtrim($DST,'&'); 

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, $base_url); 
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: '.$DST)); 
curl_setopt($ch, CURLINFO_HEADER_OUT, 1); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
$response = curl_exec($ch); 
$info = curl_getinfo($ch); 
curl_close($ch); 

所以,这个代码是多少挣扎,它仍然产生错误
在一个话题中,我读过这个阶段不需要令牌 - 无论有没有 - 无关紧要 - 仍然是相同的错误
试图玩时间(设定UTC) - 同样的错误
还我试图用某人的工作代码一样this但并没有为我
为什么我不使用某人的lib工作 - 因为我想通过算法中一步一步的,但我厌倦了这和neeed的帮助

thx提前,任何帮助表示赞赏,可能会得到一个工作分步指南的例子吗?

回答

0

似乎有你的代码错误几件事情:

1)你的参数数组应包含代替的oauth_token

$params = array(
    rawurlencode('oauth_nonce')=>rawurlencode($oauth_nonce), 
    rawurlencode('oauth_callback')=>rawurlencode($oauth_callback), 
    rawurlencode('oauth_signature_method')=>rawurlencode($oauth_signature_method), 
    rawurlencode('oauth_timestamp')=>rawurlencode($oauth_timestamp), 
    rawurlencode('oauth_consumer_key')=>rawurlencode($oauth_consumer_key), 
    rawurlencode('oauth_version')=>rawurlencode($oauth_version), 
); 

2)请求令牌您的签名密钥应当建立oauth_consumer_key使用oauth_consumer_secret后跟&符号:

$ oauth_signing_key = rawurlencode($ oauth_consumer_secret)。' &';

3)您似乎没有在授权标头中的任何位置设置签名。不要:

$DST ='OAuth '; 
foreach($params as $key=>$value){ 
    $DST .= $key.'='.'"'.$value.'"&'; 
} 
$DST .= 'oauth_signature='.rawurlencode($oauth_signature) 
+0

1 - 我的错误,它存在,oauth_token也在那里 - 我放弃它。 2 - 用你的替换签名密钥。 3 - 给$ params添加签名''params ['oauth_signature'] = rawurlencode($ oauth_signature)''。结果:'[request_header] => GET/oauth/request_token HTTP/1。1个 主机:api.twitter.com 接受:*/* 授权:OAuth的oauth_callback = “HTTP%3A%2F%2Ftwoends.home%2Fbackend” &oauth_consumer_key = “CONSUMER_KEY” &oauth_nonce = “45ed597e5456715d6880cf73d702a7df” &oauth_signature =“5ap7idjtbcdlBAeAx3HSVQpLqBk%3D “&oauth_signature_method =”HMAC-SHA1“&oauth_timestamp =”1381843238“&oauth_version =”1.0“'仍然失败 – alexZT

+0

正如我写的答案 - 看到头通过GET请求发送,添加了选项'curl_setopt($ ch,CURLOPT_POST,true);'现在我收到http错误 - 400,但没有收到 - “无法验证oauth签名和令牌” – alexZT

+0

我认为我看到了问题。在授权标题中,参数应该用逗号和空格分隔,而不是与&符分开。 ($ DST。= $ key。'='。'''。$ value。',';) –

0

我想借此在一个问题一个新的面貌,并发布新的数据
感谢@Jonny S I发现一些错误,并得到了另一个错误=)

所以,我流程现在看起来:

函数生成随机数,附加信息:oauth_nonce in apioauth.net

function generate_nonce() { 
    $mt = microtime(); 
    $rand = mt_rand(); 

    return md5($mt . $rand); // md5s look nicer than numbers 
} 

Implementing Sign in with Twitter(此链接向我们展示了,我们应该提前发布了什么头),并显示我们的方向移动 - POST oauth/request_token
此网页的链接与oauth docs section 6.1
那里,我们可以找到需要什么样的参数来请求令牌,但在官方文档中,您不会在twitter API中找到“oauth_calback”参数,它是必需的参数!

下一步骤中,我做 - 收集所需PARAMS:

  • oauth_consumer_key

    $oauth_consumer_key = 'YoUrS KEy FrOm aPP ApI'; 
    
  • oauth_nonce

    $oauth_nonce = generate_nonce(); 
    
  • oauth_callback

    $oauth_callback = 'http://twoends.home/backend'; 
    
  • oauth_sinature_method

    $oauth_signature_method = 'HMAC-SHA1'; 
    
  • oauth_timestamp

    $oauth_timestamp = time(); 
    
  • oauth_version

    $oauth_version = '1.0'; 
    
  • 附加段米(在过程中需要):

  • OAuth的签名(最棘手的部分)

这里我们对如何做到这一点Creating a signature

首先我们需要收集所有所需的PARAMS在一起的API页面,百分比编码和排序他们,我推他们阵列:

$params = array(
     rawurlencode('oauth_consumer_key')=>rawurlencode($oauth_consumer_key), 
     rawurlencode('oauth_nonce')=>rawurlencode($oauth_nonce), 
     rawurlencode('oauth_callback')=>rawurlencode($oauth_callback), 
     rawurlencode('oauth_signature_method')=>rawurlencode($oauth_signature_method), 
     rawurlencode('oauth_timestamp')=>rawurlencode($oauth_timestamp), 
     rawurlencode('oauth_version')=>rawurlencode($oauth_version), 
    ); 

然后排序:

ksort($params); 

然后我创建参数字符串:

$parameter_string = http_build_query($params,'','&'); 

结果:

PARAM字符串:oauth_callback = HTTP%253A%252F%252Ftwoends 。家里%252Fbackend & oauth_consumer_key = oauth_consumer_key_wQjQ7u5lgwA & oauth_nonce = 46fa649c21ac5315d4d4510ff68a d630 & oauth_signature_method = HMAC-SHA1 & oauth_timestamp = 1381930918 & oauth_version = 1。0

我需要创建base_string,这将被用于创建签名数据PARAM为hash_hmac()函数

$base_string = strtoupper($http_method).'&'; 
    $base_string .= rawurlencode($base_url).'&'; 
    $base_string .= rawurlencode($parameter_string); 

结果:

POST & HTTPS%3A %2F%2Fapi.twitter.com%2Foauth%2Frequest_token & oauth_callback%3Dhttp%25253A%25252F%25252Ftwoends.home%25252Fbackend%26oauth_consumer_key%3Dapp_cons_keyQjQ7u5lgwA%26oauth_nonce%3D46fa649c21 ac5315d4d4510ff68ad630%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1381930918%26oauth_version%3D1.0

下一个我从APP的设置获得CONSUMER_SECRET创建将被用于创建签名在hash_hmac第三PARAM签名密钥()函数

$oauth_consumer_secret = 'consumer_secret_from_app_settings'; 
    $oauth_signing_key = rawurlencode($oauth_consumer_secret).'&'; 

一两件事提:在第一步(request_token我们不需要把任何令牌)

此步骤创建签名:

$oauth_signature = base64_encode(hash_hmac('sha1', $base_string, $oauth_signing_key, true)); 

现在我们需要添加签名参数数组和构建头字符串

$params['oauth_signature'] = rawurlencode($oauth_signature); 
    ksort($params); 

建筑物头字符串可以在Building the header string

$DST ='OAuth '; 
    foreach($params as $key=>$value){ 
     $DST .= $key.'='.'"'.$value.'", '; 
    } 
    $DST = rtrim($DST,', '); 

    //or we can make it by hand as below 

    //$DST .= 'oauth_nonce="'.rawurlencode($oauth_nonce) 
    //  .'", oauth_callback="'.rawurlencode($oauth_callback) 
    //  .'", oauth_signature_method="HMAC-SHA1", oauth_timestamp="' 
    //  .rawurlencode($oauth_timestamp).'", oauth_consumer_key="' 
    //  .rawurlencode($oauth_consumer_key).'", oauth_signature="' 
    //  .rawurlencode($oauth_signature).'", oauth_version="1.0"'; 

的最后一步(我希望)是被发现发送请求:

$ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $base_url); 
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: '.$DST)); 
    curl_setopt($ch, CURLINFO_HEADER_OUT, 1); 
    curl_setopt($ch, CURLOPT_POST, true); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 

    $response = curl_exec($ch); 
    $info = curl_getinfo($ch); 
    curl_close($ch); 

    echo '<pre>'; 
     print_r($info); 
    echo '</pre>'; 

此代码产生错误400 - 错误的请求
如果我删除curl_setopt($ ch,CURLOPT_POST,true);我得到的错误 - 401
请求信息转储:

Array 
(
    [url] => https://api.twitter.com/oauth/request_token 
    [content_type] => 
    [http_code] => 400 
    [header_size] => 66 
    [request_size] => 471 
    [filetime] => -1 
    [ssl_verify_result] => 0 
    [redirect_count] => 0 
    [total_time] => 0.710993 
    [namelookup_time] => 0.081279 
    [connect_time] => 0.23482 
    [pretransfer_time] => 0.550913 
    [size_upload] => 0 
    [size_download] => 0 
    [speed_download] => 0 
    [speed_upload] => 0 
    [download_content_length] => 0 
    [upload_content_length] => -1 
    [starttransfer_time] => 0.710976 
    [redirect_time] => 0 
    [redirect_url] => 
    [primary_ip] => 199.16.156.104 
    [certinfo] => Array 
    (
    ) 

    [primary_port] => 443 
    [local_ip] => 192.168.1.234 
    [local_port] => 54994 
    [request_header] => POST /oauth/request_token HTTP/1.1 
Host: api.twitter.com 
Accept: */* 
Authorization: OAuth oauth_callback="http%3A%2F%2Ftwoends.home%2Fbackend", oauth_consumer_key="your_consumer_keyCwQjQ7u5lgwA", oauth_nonce="1ba83f0af239f439c1524096c33faefe", oauth_signature="QZZvrJ8wzCQOYhiKJeT4vz%2FWCcg%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1381931941", oauth_version="1.0" 
Content-Length: -1 
Content-Type: application/x-www-form-urlencoded 
Expect: 100-continue 


) 

希望这将有助于了解在哪里可以找到错误,事先我还会尝试使用Fiddler跟踪请求

--- ------------------------------------
使用新的API解决方案

+0

使用了新的API [POST oauth2/token](https://dev.twitter.com/docs/api/1.1/post/oauth2/token),它花了我几分钟才能使它工作,我想它应该在旧的API中注意它的有用性 – alexZT

+1

如果您只想代表您的应用程序发出请求,oauth2持票人令牌没有问题。如果您希望能够代表另一个用户执行操作,您仍然需要使用oauth 1.0a。 –

0

它看起来像oauth_callback url正在basetring中进行三重编码。它应该是这样的形式:

POST&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token& 
oauth_callback%3Dhttp%253A%252F%252Ftwoends.home%252Fbackend%26 
oauth_consumer_key%3Dapp_cons_keyQjQ7u5lgwA ... 

在你即basestring:

oauth_callback%3Dhttp%25253A%25252F%25252Ftwoends.home%25252Fbackend 

的罪魁祸首似乎是 'http_build_query'。

+0

感谢您的建议,我使用新的API和oauth2,它的工作原理!我想这是原因,并感谢提琴手 - 很酷的事情=) – alexZT

+1

oauth2持票人令牌没有问题,如果你只想代表你的应用程序发出请求。如果您希望能够代表另一个用户执行操作,您仍然需要使用oauth 1.0a。 –

+0

排除 'http_build_query':'$ PARAMS =阵列( 'oauth_consumer_key'=> $ oauth_consumer_key, 'oauth_nonce'=> $ oauth_nonce, 'oauth_callback'=> $ oauth_callback, 'oauth_signature_method'=> $ oauth_signature_method, ' oauth_timestamp'=> $ oauth_timestamp, 'oauth_version'=> $ oauth_version, ); $ parameter_string =''; ($ params as $ key => $ param){ $ parameter_string。= rawurlencode($ key)。'&'。rawurlencode($ param); ($ key)。'='。rawurlencode($('$'))$ parameter_string = rtrim($ parameter_string,'&');' – alexZT