【发布时间】:2014-02-21 19:17:15
【问题描述】:
我使用的是 OAuth 消费者组件 2.1.0 和 CakePHP 2.4.4。 我想实现“使用 Twitter 登录”。
这里是代码。
应用程序/控制器/组件/OAuthConsumers/TwitterConsumer.php:
<?php
class TwitterConsumer extends AbstractConsumer {
public function __construct() {
parent::__construct('xxxxxxxxxxxxxxxxxxxxxx', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
}
}
?>
app/Controller/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]
我在 app/Controller/Component/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>
如何解决这个问题?
谢谢。
【问题讨论】:
-
你检查了回调方法中$requestToken变量的值吗?
-
$requestToken 值为:
object(__PHP_Incomplete_Class)#4 (3) { ["__PHP_Incomplete_Class_Name"]=> string(10) "OAuthToken" ["key"]=> string(42) "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" ["secret"]=> string(41) "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" }` -
我认为您必须在控制器顶部添加
App::uses('OAuthConsumerComponent', 'Controller/Component');。