使用PHP进行Twitter身份验证:#89令牌无效或过期

时间:2014-10-29 09:40:38

标签: php twitter

我正在尝试让我的身份验证例程让Twitter工作,但到目前为止,我一直没有成功。我使用两个PHP框架,一个更容易连接到Twitter:Codebird和一个处理数据库和所有其他东西:Yii。

它的工作方式是这样的:

  1. 用户打开管理页面。该页面从我的API请求登录URL(再次从Twitter请求)。
  2. 用户授权该应用。
  3. 服务器存储令牌以供将来使用。
  4. 我的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 个答案:

答案 0 :(得分:0)

好吧,就像平常一样 - 在我发布这里的东西之后,我设法自己解决它。

问题是验证部分丢失了所以我将授权位更改为:

...
                $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
    }
}