2014-10-29 110 views
0

我试图让我的Twitter身份验证例程正常工作,但到目前为止,我一直不成功。我使用两个PHP框架,一个更容易连接到Twitter:Codebird,另一个处理数据库和其他所有东西:Yii。使用PHP进行Twitter身份验证:#89无效或过期的令牌

它应该工作的方式是这样的:

  1. 用户打开管理页面。该页面从我的API请求登录网址(它再次从Twitter请求)。
  2. 用户授权应用程序。
  3. 服务器存储令牌以备将来使用。

我的Twitter类:

require 'vendor/autoload.php'; 

use Codebird\Codebird; 

class Twitter 
{ 
    protected $consumer_key = 'xx'; 
    protected $consumer_secret = 'xx'; 
    protected $access_token = 'xx'; 
    protected $access_secret = 'xx'; 
    protected $twitter; 

    public function __construct($key = null, $secret = null) 
    { 
     // Fetch new Twitter Instance 
     Codebird::setConsumerKey($this->consumer_key, $this->consumer_secret); 
     $this->twitter = Codebird::getInstance(); 

     // Set access token 
     if(is_null($key)) : 
      $this->setToken($this->access_token, $this->access_secret); 
     else : 
      $this->setToken($key, $secret); 
     endif; 
    } 

    public function tweet($message) 
    { 
     $params = array(
      'status' => $message 
     ); 
     return $this->twitter->statuses_update($params); 
    } 

    public function tweetWithImage($message, $image_url) 
    { 
     $params = array(
      'status' => $message, 
      'media[]' => $image_url 
     ); 
     return $this->twitter->statuses_updateWithMedia($params); 
    } 

    public function setToken($key, $secret) 
    { 
     return $this->twitter->setToken($key, $secret); 
    } 

    public function getBearerToken() { 
     return $this->twitter->oauth2_token(); 
    } 

    public function getRequestToken($ident) { 
     $reply = $this->twitter->oauth_requestToken(array(
      'oauth_callback' => 'http://api.exxica.com/publisher/twitter/authorize?ident='.$ident 
     )); 
     return $reply; 
    } 

    public function getUserData($fields = false) { 
     return $this->twitter->account_verifyCredentials(array('include_entities' => $fields)); 
    } 

    public function verifyToken($oauth_verifier) { 
     $reply = $this->twitter->oauth_accessToken(array(
      'oauth_verifier' => $oauth_verifier 
     )); 
     return $reply; 
    } 

    public function generateTokens($ident) { 
     // get the request token 
     $reply = $this->getRequestToken($ident); 

     $this->setToken($reply->oauth_token, $reply->oauth_token_secret); 

     // Stores the tokens 
     $cr = new CDbCriteria(); 
     $cr->compare('user_id', $ident); 
     $client = _Twitter::model()->find($cr); 
     if(is_null($client)) $client = new _Twitter; 
     $client->user_id = $ident; 
     $client->access_token = $reply->oauth_token; 
     $client->access_secret = $reply->oauth_token_secret; 
     $client->save(); 
    } 

    public function getAuthUrl() { 
     return $this->twitter->oauth_authorize(); 
    } 
} 

登录程序(如预期运作 - 虽然我有一种感觉,它存储了错误的值):

  ... 
       $twitter = new Twitter(); 
       $twitter->generateTokens($identity->id); 
       $output = array('success' => true, 'loginUrl' => $twitter->getAuthUrl()); 
       $this->render('echo', array('response'=> $output)); 
      ... 

授权程序:

  ... 
      // Receives redirect from Twitter 
      if(!empty($_GET['oauth_verifier'])) { 
       $oauth_verifier = $_GET['oauth_verifier']; 
       $ident = $_GET['ident']; 

       $cr = new CDbCriteria(); 
       $cr->compare('user_id', $ident); 
       $client = _Twitter::model()->find($cr); 

       // Set the request token 
       $twitter = new Twitter($client->access_token, $client->access_secret); 

       $twitter_user = $twitter->getUserData(array('screen_name')); 

       $client->user_id = $ident; 
       $client->account_name = $twitter_user->screen_name; 
       $client->lastused = date('Y-m-d H:i:s', time()); 
       $client->expires = date('Y-m-d H:i:s', strtotime('+2 months')); 
       $client->save(); 
       $output = array( 
        'success' => true, 
        'twitter_user' => $twitter_user, 
        'client' => $client 
       ); 

      } else { 
       $output = array('success' => false); 
      } 

      $this->render('echo', array('response' => $output)); 
      ... 

而我得到的回报是这样的:

{ 
    "success": true, 
    "twitter_user": { 
     "errors": [ 
      { 
       "message": "Invalid or expired token", 
       "code": 89 
      } 
     ], 
     "httpstatus": 401, 
     "rate": null 
    }, 
    "client": { 
     "ID": "7", 
     "user_id": "25", 
     "account_name": null, 
     "access_token": "xxxx", 
     "access_secret": "xxxx", 
     "created": "2014-10-20 10:59:06", 
     "expires": "2014-12-29 09:06:22", 
     "lastused": "2014-10-29 09:06:22" 
    } 
} 

正如所看到的,它总是返回[89] Invalid or expired token我读过网上是因为我莫名其妙地提交了错误的令牌。但我似乎无法让它与任何其他标记一起使用,而不是我在Twitter类的声明中使用的标记(从Twitter应用程序许可页粘贴)。所以我想知道我做错了什么?我该怎么做才能让它按原样工作?

PS。请记住,这段代码是一周调试的产物,可能因此缺少一些重要部分。如存储授权的访问令牌。

回答

1

那么,像往常一样 - 在我发布了一些东西之后,我设法自己解决它。

的问题是,验证部分缺失,所以当我改变了授权位:

... 
       $twitter = new Twitter($client->access_token, $client->access_secret); 

       $reply = $twitter->verifyToken($oauth_verifier); // Added this 

       if($reply->httpstatus == 200) { // Added this IF 
        $client->user_id = $ident; 
        $client->account_name = $reply->screen_name; 
        $client->access_token = $reply->oauth_token; 
        $client->access_secret = $reply->oauth_token_secret; 
        $client->lastused = date('Y-m-d H:i:s', time()); 
        $client->expires = date('Y-m-d H:i:s', strtotime('+2 months')); 
        $client->save(); 
        $output = array( 
         'success' => true, 
         'client' => $client, 
         'reply' => $reply 
        ); 
       } else { 
        $output = array( 
         'success' => false, 
         'reply' => $reply 
        ); 
       } 
... 

它返回这个(我已经删值):

{ 
    "success": true, 
    "client": { 
     "ID": "7", 
     "user_id": "25", 
     "account_name": USER_NAME, 
     "access_token": USER_TOKEN, 
     "access_secret": USER_SECRET, 
     "created": "2014-10-20 10:59:06", 
     "expires": "2014-12-29 10:26:46", 
     "lastused": "2014-10-29 10:26:46" 
    }, 
    "reply": { 
     "oauth_token": USER_TOKEN, 
     "oauth_token_secret": USER_SECRET, 
     "user_id": USER_ID, 
     "screen_name": USER_NAME, 
     "httpstatus": 200, 
     "rate": null 
    } 
} 
相关问题