2014-02-20 182 views
1

我使用的是OAuth使用者組件2.1.0和CakePHP 2.4.4。 ,我想實現「使用Twitter登錄」。CakePHP2&Twitter OAuth:無效/過期令牌

這是代碼。

應用/控制器/組件/ OAuthConsumers/TwitterConsumer.php:

<?php 
class TwitterConsumer extends AbstractConsumer { 
    public function __construct() { 
     parent::__construct('xxxxxxxxxxxxxxxxxxxxxx', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'); 
    } 
} 
?> 

應用/控制器/ UserController.php:

登錄:

$requestToken = $this->OAuthConsumer->getRequestToken('Twitter', 'https://api.twitter.com/oauth/request_token', 'http://' . $_SERVER['HTTP_HOST'] . '/users/oauth_callback'); 

    if ($requestToken) { 
     $this->Session->write('twitter_request_token', $requestToken); 
     $this->redirect('https://api.twitter.com/oauth/authorize?oauth_token=' . $requestToken->key); 
    } else { 
     // an error occured when obtaining a request token 
    } 

    $this->autoLayout = false; 

回調:

$requestToken = $this->Session->read('twitter_request_token'); 
    $accessToken = $this->OAuthConsumer->getAccessToken('Twitter', 'https://api.twitter.com/oauth/access_token', $requestToken); 

    if ($accessToken) { 
     $profile = json_decode($this->OAuthConsumer->get('Twitter',$accessToken->key, $accessToken->secret, 'https://api.twitter.com/1/account/verify_credentials.json')); 
     // Add user 
     $this->User->update(
      Array(
       "user_id" => $profile['id_str'], 
       "username" => $profile['screen_name'], 
       "oauth_token_key" => $accessToken->key, 
       "oauth_token_secret" => $accessToken->secret, 
      ) 
     ); 
     $this->data['User']['access_token_key'] = $accessToken->key; 
     $this->data['User']['access_token_secret'] = $accessToken->secret; 

     if ($this->Auth->login($this->data)) { 
       $this->redirect($this->Auth->redirect()/*'/'*/); 
     } else { 
       $this->redirect('/users/login'); 
     } 
     die("OK"); 
    } else { 
     die("ERROR"); 
     $this->Session->setFlash(__('Error')); 
     $this->redirect('/users/login'); 
    } 

我試試登錄並從Twitter重定向到我的回調。但他說:

Notice (8): OAuthRequest::from_consumer_and_token(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "OAuthToken" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition [APP/Controller/Component/OAuthConsumerComponent.php, line 532] 
Notice (8): OAuthSignatureMethod_HMAC_SHA1::build_signature() [http://php.net/oauthsignaturemethod-hmac-sha1.build-signature]: The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "OAuthToken" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition [APP/Controller/Component/OAuthConsumerComponent.php, line 342] 

我加入了一些代碼的應用程序/控制器/組件/ OAuthConsumerComponent.php:

private function doRequest($request) { 
    if ($request->get_normalized_http_method() == 'POST') { 
     $data = $this->doPost($this->url, $request->to_postdata()); 
    } else { 
     $data = $this->doGet($request->to_url()); 
    } 

    var_dump($data); 

說:

<?xml version="1.0" encoding="UTF-8"?> 
<hash> 
    <error>Invalid/expired Token</error> 
    <request>/oauth/access_token</request> 
</hash> 

如何解決這個問題呢?

謝謝。

+0

您是否在回調方法中檢查$ requestToken變量的值? – dhofstet

+0

$ requestToken值爲:'對象(__ PHP_Incomplete_Class)#4(3){ [ 「__PHP_Incomplete_Class_Name」] => 串(10) 「OAuthToken」 [ 「鑰匙」] => 串(42) 「xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx」 [「secret」] => 字符串(41)「xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx」 }' ' – Palon

+0

我認爲您必須添加App :: uses('OAuthConsumerComponent','Controller/Component');'到您的頂部控制器。 – dhofstet

回答

1

自己解決。

登錄:

if ($requestToken) { 
    $this->Session->write('twitter_request_token', serialize($requestToken)); // Added serialize 
    $this->redirect('https://api.twitter.com/oauth/authorize?oauth_token=' . $requestToken->key); 
} 

回調:

$requestToken = unserialize($this->Session->read('twitter_request_token')); // Added unserialize 
$accessToken = $this->OAuthConsumer->getAccessToken('Twitter', 'https://api.twitter.com/oauth/access_token', $requestToken); 

很好地工作。

謝謝您的意見!