2013-10-14 172 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