2013-01-24 147 views
16

我正在使用Twitter將用戶登錄到網站,這似乎正在努力,直到我試圖獲得有效的訪問令牌。爲什麼我的twitter oauth訪問令牌無效/過期

require("twitteroauth.php"); 
require 'twconfig.php'; 
session_start(); 

$twitteroauth = new TwitterOAuth(YOUR_CONSUMER_KEY, YOUR_CONSUMER_SECRET); 
$request_token = $twitteroauth->getRequestToken('http://****/tw_response.php'); 

$oauth_token = $request_token['oauth_token']; 
$_SESSION['oauth_token'] = $oauth_token; 

$oauth_token_secret = $request_token['oauth_token_secret']; 
$_SESSION['oauth_token_secret'] = $oauth_token_secret; 

if ($twitteroauth->http_code == 200) { 
    url = $twitteroauth->getAuthorizeURL($request_token['oauth_token']); 
    header('Location: '.$url); 
} else { 
    die('Something wrong happened.'); 
} 

這似乎是正常工作,重定向我到Twitter要登錄並確認訪問,之後返回我tw_response.php(我的回調URL),在URL中下列變量:

http://example.com/login.php?oauth_token=sO3X...yj0k&oauth_verifier=Ip6T...gALQ 

在tw_response.php我然後嘗試獲取訪問令牌,但它報告爲無效。我試着用var_dump如下查看訪問令牌的內容:

require("twitteroauth.php"); 
require 'twconfig.php'; 
session_start(); 

$oauth_verifier = $_REQUEST['oauth_verifier']; 
$oauth_token = $_SESSION['oauth_token']; 
$oauth_token_secret = $_SESSION['oauth_token_secret']; 

$twitteroauth = new TwitterOAuth(YOUR_CONSUMER_KEY, YOUR_CONSUMER_SECRET, $oauth_token, $oauth_token_secret); 

$access_token = $twitteroauth->getAccessToken($data['oauth_verifier']); 
var_dump($access_token); 

var_dump的結果「無效/到期令牌」結尾:

array(8) { 
    ["oauth_url"] => string(104) ""1.0" encoding="UTF-8"?>/oauth/access_token?oauth_consumer_key=ceE...9Dg" 
    ["oauth_nonce"]=> string(32) "c52...d07" 
    ["oauth_signature"]=> string(28) "ry7...Fcc=" 
    ["oauth_signature_method"]=> string(9) "HMAC-SHA1" 
    ["oauth_timestamp"]=> string(10) "1359031586" 
    ["oauth_token"]=> string(40) "sO3...j0k" 
    ["oauth_verifier"]=> string(43) "Ip6...ALQ" 
    ["oauth_version"]=> string(63) "1.0 Invalid/expired Token " 
} 
+0

這是用亞伯拉罕·威廉姆斯的圖書館嗎?看起來'getAccessToken(code)'只在您調用的頁面允許用戶訪問後輸入代碼時才起作用。我認爲當你使用回調網址時你需要使用這兩個信息。 – NoBugs

+0

如果您使用有效的回調URL,則不需要使用憑證驗證'oauth_verifier'。無論如何檢查了這一點。 – Amelia

+0

您的服務器時鐘是否正確運行? –

回答

17
$access_token = $twitteroauth->getAccessToken($data['oauth_verifier']); 
var_dump($access_token); 

哪裏奇蹟般地沒有$data來自?你有變量$oauth_verifier,但請記住,如果這是你註冊的回調URL,你不需要這個。

由於您在getAccessToken中使用了無效變量,它將返回無效值。

使用TwitterOAuth對象的正確方法:

if (!isset($_GET["oauth_token"])) { 
    // set these values in a config file somewhere. 
    $twitter = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET); 

    // append a ?. This is your callback URL if you specify something. 
    $credentials = $twitter->getRequestToken("http://example.com/test.php?"); 

    // try and be a bit more elegant with the URL... This is a minimal example 
    $url = $twitter->getAuthorizeUrl($credentials); 
    echo $url; 

    // these are temporary tokens that must be used to fetch the new, 
    // permanent access tokens. store these in some way, 
    // session is a decent choice. 
    $_SESSION["token"] = $credentials["oauth_token"]; 
    $_SESSION["secret"] = $credentials["oauth_token_secret"]; 
} else { 

    // use the user's previously stored temporary credentials here 
    $twitter = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, 
        $_SESSION["token"], $_SESSION["secret"]); 

    // uses the oauth_token (from the request) already. 
    // you store these credentials in your database (see below). 
    $credentials = $twitter->getAccessToken($_GET["oauth_verifier"]); 

    // just a printout of credentials. store these, don't display them. 
    echo "<pre>"; 
    var_dump($credentials); 
    // valid credentials, provided you give the app access to them. 
    echo "</pre>"; 
} 

我只是用了回調,易於使用的一個腳本;如果你喜歡(你可能應該),你可以將相關部分分成多個腳本。

對於您的數據庫,證書還包括twitter用戶的用戶名。
編輯Twitter is now allocating 64bit integers for user IDs。您應該將此字符串存儲爲字符串,以確保您不會在應用程序的每個部分都無法處理64位整數,從而導致出現嚴重的用戶ID和衝突。

array(4) { 
    ["oauth_token"]=> 
    string(50) "7041...wYupkS" 
    ["oauth_token_secret"]=> 
    string(42) "O9ENq...21B2fk" 
    ["user_id"]=> // user ID. always the same, never changes (store this as ID) 
    string(9) "..." 
    ["screen_name"]=> // username. can change. 
    string(11) "..." 
} 

所以,如果你想登錄的用戶在通過Twitter,沒有明確地給他們登錄到你的網站,你可以使用$_SESSION(我用的數據庫爲我登錄,這是建議,如果你想保存狀態) 在上面的腳本,你想補充一點的else塊的結尾:

$_SESSION["token"] = $credentials["oauth_token"]; 
$_SESSION["secret"] = $credentials["oauth_secret"]; 
$_SESSION["username"] = $credentials["screen_name"]; 

您也可以獲取用戶的網名,更從GET account/verify_credentials,如果你想給他們一個用戶頁面(如你使用javascript,通過id_str在這裏抓住他們的用戶ID):

$user_array = $twitter->get("account/verify_credentials"); 
+0

+1不錯的解決方案Hiroto!但是,我們如何獲得用戶的電子郵件? – Arash

+0

@Arash用戶電子郵件是私人的;您應該存儲用戶的ID。聯繫與電子郵件通知用戶將要求他們給你他們的電子郵件與他們的明確同意(通過輸入它變成一種形式) – Amelia

+0

@Amelia當我做了'的var_dump($憑證)',我得到了一個數組元素更多:' [「x_auth_expires」] =>字符串(1)「0」'。我認爲這是它給我'無效/過期令牌'的原因。你能告訴我如何解決這個問題嗎? –

0

如果您的OAuth流是工作一天,沒有了下,檢查您的計算機的時鐘。我運行一個流浪盒子,不知怎的,有它的時間之前設置的一天,這引起了Twitter的API返回{「代碼」:89,「消息」:「憑證無效或過期」}。這也可能表現爲401時間戳越界。您可以使用此命令在Ubuntu更新您的時鐘:

sudo ntpdate time.nist.gov 

Alternative method如果ntpdate不可用您的系統上:

sudo date -s "$(wget -qSO- --max-redirect=0 google.com 2>&1 | grep Date: | cut -d' ' -f5-8)Z"