2014-02-20 147 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); 

很好地工作。

谢谢您的意见!