php Twitter API 返回错误 215,错误的身份验证数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12684765/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 04:01:45  来源:igfitidea点击:

Twitter API returns error 215, Bad Authentication Data

phpapitwitter

提问by Dip Dhingani

I am trying to call following Twitter's API to get a list of followers for a user.

我正在尝试调用 Twitter 的 API 来获取用户的关注者列表。

http://api.twitter.com/1.1/followers/ids.json?cursor=-1&screen_name=username

http://api.twitter.com/1.1/followers/ids.json?cursor=-1&screen_name=username

And I am getting this error message in response.

我收到此错误消息作为回应。

{
    code = 215;
    message = "Bad Authentication data";
}

I can't seem to find the documentation related to this error code. Anyone has any idea about this error?

我似乎找不到与此错误代码相关的文档。有人对这个错误有任何想法吗?

回答by A Bright Worker

A very concise code without any other php file include of oauth etc. Please note to obtain following keys you need to sign up with https://dev.twitter.comand create application.

一个非常简洁的代码,没有任何其他 php 文件,包括 oauth 等。请注意要获取以下密钥,您需要使用https://dev.twitter.com 注册并创建应用程序。

<?php
$token = 'YOUR_TOKEN';
$token_secret = 'YOUR_TOKEN_SECRET';
$consumer_key = 'CONSUMER_KEY';
$consumer_secret = 'CONSUMER_SECRET';

$host = 'api.twitter.com';
$method = 'GET';
$path = '/1.1/statuses/user_timeline.json'; // api call path

$query = array( // query parameters
    'screen_name' => 'twitterapi',
    'count' => '5'
);

$oauth = array(
    'oauth_consumer_key' => $consumer_key,
    'oauth_token' => $token,
    'oauth_nonce' => (string)mt_rand(), // a stronger nonce is recommended
    'oauth_timestamp' => time(),
    'oauth_signature_method' => 'HMAC-SHA1',
    'oauth_version' => '1.0'
);

$oauth = array_map("rawurlencode", $oauth); // must be encoded before sorting
$query = array_map("rawurlencode", $query);

$arr = array_merge($oauth, $query); // combine the values THEN sort

asort($arr); // secondary sort (value)
ksort($arr); // primary sort (key)

// http_build_query automatically encodes, but our parameters
// are already encoded, and must be by this point, so we undo
// the encoding step
$querystring = urldecode(http_build_query($arr, '', '&'));

$url = "https://$host$path";

// mash everything together for the text to hash
$base_string = $method."&".rawurlencode($url)."&".rawurlencode($querystring);

// same with the key
$key = rawurlencode($consumer_secret)."&".rawurlencode($token_secret);

// generate the hash
$signature = rawurlencode(base64_encode(hash_hmac('sha1', $base_string, $key, true)));

// this time we're using a normal GET query, and we're only encoding the query params
// (without the oauth params)
$url .= "?".http_build_query($query);
$url=str_replace("&amp;","&",$url); //Patch by @Frewuill

$oauth['oauth_signature'] = $signature; // don't want to abandon all that work!
ksort($oauth); // probably not necessary, but twitter's demo does it

// also not necessary, but twitter's demo does this too
function add_quotes($str) { return '"'.$str.'"'; }
$oauth = array_map("add_quotes", $oauth);

// this is the full value of the Authorization line
$auth = "OAuth " . urldecode(http_build_query($oauth, '', ', '));

// if you're doing post, you need to skip the GET building above
// and instead supply query parameters to CURLOPT_POSTFIELDS
$options = array( CURLOPT_HTTPHEADER => array("Authorization: $auth"),
                  //CURLOPT_POSTFIELDS => $postfields,
                  CURLOPT_HEADER => false,
                  CURLOPT_URL => $url,
                  CURLOPT_RETURNTRANSFER => true,
                  CURLOPT_SSL_VERIFYPEER => false);

// do our business
$feed = curl_init();
curl_setopt_array($feed, $options);
$json = curl_exec($feed);
curl_close($feed);

$twitter_data = json_decode($json);


foreach ($twitter_data as &$value) {
   $tweetout .= preg_replace("/(http:\/\/|(www\.))(([^\s<]{4,68})[^\s<]*)/", '<a href="http://" target="_blank"></a>', $value->text);
   $tweetout = preg_replace("/@(\w+)/", "<a href=\"http://www.twitter.com/\1\" target=\"_blank\">@\1</a>", $tweetout);
   $tweetout = preg_replace("/#(\w+)/", "<a href=\"http://search.twitter.com/search?q=\1\" target=\"_blank\">#\1</a>", $tweetout);
}

echo $tweetout;

?>

Regards

问候

回答by Pavel

The only solution I've found so far is:

到目前为止,我找到的唯一解决方案是:

  • Create application in twitter developer panel
  • Authorize user with your application (or your application in user account) and save "oauth_token" and "oauth_token_secret" which Twitter gives you. Use TwitterOAuthlibrary for this, it's pretty easy, see examples coming with library.
  • Using this tokens you can make authenticated requests on behalf of user. You can do it with the same library.

    // Arguments 1 and 2 - your application static tokens, 2 and 3 - user tokens, received from Twitter during authentification  
    $connection = new TwitterOAuth(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET, $tokens['oauth_token'], $tokens['oauth_token_secret']);  
    $connection->host = 'https://api.twitter.com/1.1/'; // By default library uses API version 1.  
    $friendsJson = $connection->get('/friends/ids.json?cursor=-1&user_id=34342323');  
    
  • 在 Twitter 开发者面板中创建应用程序
  • 使用您的应用程序(或您的用户帐户中的应用程序)授权用户并保存 Twitter 给您的“oauth_token”和“oauth_token_secret”。为此使用TwitterOAuth库,这很简单,请参阅库附带的示例。
  • 使用此令牌,您可以代表用户发出经过身份验证的请求。你可以用同一个库来做到这一点。

    // Arguments 1 and 2 - your application static tokens, 2 and 3 - user tokens, received from Twitter during authentification  
    $connection = new TwitterOAuth(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET, $tokens['oauth_token'], $tokens['oauth_token_secret']);  
    $connection->host = 'https://api.twitter.com/1.1/'; // By default library uses API version 1.  
    $friendsJson = $connection->get('/friends/ids.json?cursor=-1&user_id=34342323');  
    

This will return you list of user's friends.

这将返回用户的好友列表。

回答by Dante Cullari

FOUND A SOLUTION - using the Abraham TwitterOAuth library. If you are using an older implementation, the following lines should be added after the new TwitterOAuth object is instantiated:

找到解决方案 - 使用Abraham TwitterOAuth 库。如果您使用的是较旧的实现,则应在实例化新的 TwitterOAuth 对象后添加以下行:

$connection->host = "https://api.twitter.com/1.1/";
$connection->ssl_verifypeer = TRUE;
$connection->content_type = 'application/x-www-form-urlencoded';

The first 2 lines are now documented in Abraham library Readme file, but the 3rd one is not. Also make sure that your oauth_version is still 1.0.

前两行现在记录在 Abraham 库自述文件中,但第三行没有。还要确保您的 oauth_version 仍然是 1.0。

Here is my code for getting all user data from 'users/show' with a newly authenticated user and returning the user full name and user icon with 1.1 - the following code is implemented in the authentication callback file:

这是我的代码,用于使用新验证的用户从“u​​sers/show”获取所有用户数据,并使用 1.1 返回用户全名和用户图标 - 以下代码在身份验证回调文件中实现:

session_start();
require ('twitteroauth/twitteroauth.php');
require ('twitteroauth/config.php');

$consumer_key = '****************';
$consumer_secret = '**********************************';

$to = new TwitterOAuth($consumer_key, $consumer_secret);

$tok = $to->getRequestToken('http://exampleredirect.com?twitoa=1');

$token = $tok['oauth_token'];
$secret = $tok['oauth_token_secret'];

//save tokens to session
$_SESSION['ttok'] = $token;
$_SESSION['tsec'] = $secret;

$request_link = $to->getAuthorizeURL($token,TRUE);

header('Location: ' . $request_link);

The following code then is in the redirect after authentication and token request

以下代码位于身份验证和令牌请求后的重定向中

if($_REQUEST['twitoa']==1){
    require ('twitteroauth/twitteroauth.php');
    require_once('twitteroauth/config.php');
    //Twitter Creds
    $consumer_key = '*****************';
    $consumer_secret = '************************************';

    $oauth_token = $_GET['oauth_token']; //ex Request vals->http://domain.com/twitter_callback.php?oauth_token=MQZFhVRAP6jjsJdTunRYPXoPFzsXXKK0mQS3SxhNXZI&oauth_verifier=A5tYHnAsbxf3DBinZ1dZEj0hPgVdQ6vvjBJYg5UdJI

    $ttok = $_SESSION['ttok'];
    $tsec = $_SESSION['tsec'];

    $to = new TwitterOAuth($consumer_key, $consumer_secret, $ttok, $tsec);
    $tok = $to->getAccessToken();
    $btok = $tok['oauth_token'];
    $bsec = $tok['oauth_token_secret'];
    $twit_u_id = $tok['user_id'];
    $twit_screen_name = $tok['screen_name'];

    //Twitter 1.1 DEBUG
    //print_r($tok);
    //echo '<br/><br/>';
    //print_r($to);
    //echo '<br/><br/>';
    //echo $btok . '<br/><br/>';
    //echo $bsec . '<br/><br/>';
    //echo $twit_u_id . '<br/><br/>';
    //echo $twit_screen_name . '<br/><br/>';

    $twit_screen_name=urlencode($twit_screen_name);
    $connection = new TwitterOAuth($consumer_key, $consumer_secret, $btok, $bsec);
    $connection->host = "https://api.twitter.com/1.1/";
    $connection->ssl_verifypeer = TRUE;
    $connection->content_type = 'application/x-www-form-urlencoded';
    $ucontent = $connection->get('users/show', array('screen_name' => $twit_screen_name));

    //echo 'connection:<br/><br/>';
    //print_r($connection);
    //echo '<br/><br/>';
    //print_r($ucontent);

    $t_user_name = $ucontent->name;
    $t_user_icon = $ucontent->profile_image_url;

    //echo $t_user_name.'<br/><br/>';
    //echo $t_user_icon.'<br/><br/>';
}

It took me way too long to figure this one out. Hope this helps someone!!

我花了太长时间才弄明白这一点。希望这对某人有帮助!!

回答by christopher

UPDATE:Twitter API 1 is now deprecated. Refer to above answer.

更新:Twitter API 1 现已弃用。参考上面的回答。

Twitter 1.1 does not work with that syntax (when I wrote this answer). Needs to be 1, not 1.1. This will work:

Twitter 1.1 不适用于该语法(当我写这个答案时)。需要是 1,而不是 1.1。这将起作用:

http://api.twitter.com/1/followers/ids.json?cursor=-1&screen_name=username

http://api.twitter.com/1/followers/ids.json?cursor=-1&screen_name=username

回答by spiele_r

The url with /1.1/in it is correct, it is the new Twitter API Version 1.1.

里面的 url/1.1/是正确的,它是新的 Twitter API 版本 1.1。

But you need an application and authorize your application (and the user) using oAuth.

但是您需要一个应用程序并使用 oAuth 授权您的应用程序(和用户)。

Read more about this on the Twitter Developers documentation site:)

Twitter 开发人员文档站点上阅读更多相关信息 :)

回答by Jonathan Haar

The answer by Gruik worked for me in the below thread.

Gruik 的回答在下面的线程中为我工作。

{Excerpt | Zend_Service_Twitter - Make API v1.1 ready}

{摘录| Zend_Service_Twitter - 准备好 API v1.1}

with ZF 1.12.3 the workaround is to pass consumerKey and consumerSecret in oauthOptions option, not directrly in the options.

对于 ZF 1.12.3,解决方法是在 oauthOptions 选项中传递 consumerKey 和 consumerSecret,而不是直接在选项中传递。

    $options = array(
        'username' => /*...*/,
        'accessToken' => /*...*/,
        'oauthOptions' => array(
            'consumerKey' => /*...*/,
            'consumerSecret' => /*...*/,
        )
    );

回答by nobug

After two days of research I finally found that to access s.o. public tweets you just need anyapplication credentials, and not that particular user ones. So if you are developing for a client, you don't have to ask them to do anything.

经过两天的研究,我终于发现要访问如此公开的推文,您只需要任何应用程序凭据,而不是特定的用户凭据。因此,如果您正在为客户进行开发,则不必要求他们做任何事情。

To use the new Twitter API 1.1 you need two things:

要使用新的 Twitter API 1.1,您需要做两件事:

First, you can (actually have to) create an application with your owncredentials and then get the Access token(OAUTH_TOKEN) and Access token secret(OAUTH_TOKEN_SECRET) from the "Your access token" section. Then you supply them in the constructor for the new TwitterOAuth object. Now you can access anyonepublic tweets.

首先,您可以(实际上必须)使用您自己的凭据创建一个应用程序,然后从“您的访问令牌”部分获取访问令牌(OAUTH_TOKEN) 和访问令牌机密(OAUTH_TOKEN_SECRET) 。然后在新 TwitterOAuth 对象的构造函数中提供它们。现在您可以访问任何人的公开推文。

$connection = new TwitterOAuth( CONSUMER_KEY, CONSUMER_SECRET, OAUTH_TOKEN, OAUTH_TOKEN_SECRET );

$connection->host = "https://api.twitter.com/1.1/"; // change the default
$connection->ssl_verifypeer = TRUE;
$connection->content_type = 'application/x-www-form-urlencoded';

$tweets = $connection->get('http://api.twitter.com/1.1/statuses/user_timeline.json?screen_name='.$username.'&count='.$count);

Actually I think this is what Pavelhas suggested also, but it is not so obvious from his answer.

实际上,我认为这也是Pavel所建议的,但从他的回答中并没有那么明显。

Hope this saves someone else those two days :)

希望这两天能拯救别人:)

回答by Maksim Kotlyar

This might help someone who use Zend_Oauth_Client to work with twitter api. This working config:

这可能会帮助使用 Zend_Oauth_Client 的人使用 twitter api。这个工作配置:

$accessToken = new Zend_Oauth_Token_Access();
$accessToken->setToken('accessToken');
$accessToken->setTokenSecret('accessTokenSecret');

$client = $accessToken->getHttpClient(array(
    'requestScheme' => Zend_Oauth::REQUEST_SCHEME_HEADER,
    'version' => '1.0', // it was 1.1 and I got 215 error.
    'signatureMethod' => 'HMAC-SHA1',
    'consumerKey' => 'foo',
    'consumerSecret' => 'bar',
    'requestTokenUrl' => 'https://api.twitter.com/oauth/request_token',
    'authorizeUrl' => 'https://api.twitter.com/oauth/authorize',
    'accessTokenUrl' => 'https://api.twitter.com/oauth/access_token',
    'timeout' => 30
));

It look like twitter api 1.0 allows oauth version to be 1.1 and 1.0, where twitter api 1.1 require only oauth version to be 1.0.

看起来 twitter api 1.0 允许 oauth 版本为 1.1 和 1.0,其中 twitter api 1.1 只需要 oauth 版本为 1.0。

P.S We do not use Zend_Service_Twitter as it does not allow send custom params on status update.

PS 我们不使用 Zend_Service_Twitter 因为它不允许在状态更新时发送自定义参数。

回答by Juan de Parras

You need to send customerKeyand customerSecretto Zend_Service_Twitter

您需要将customerKeycustomerSecret发送到 Zend_Service_Twitter

$twitter = new Zend_Service_Twitter(array(
                'consumerKey' => $this->consumer_key,
                'consumerSecret' => $this->consumer_secret,
                'username' => $user->screenName,
                'accessToken' => unserialize($user->token)
));

回答by Victor

Be sure that you have read AND write access for application in twitter

确保您对 twitter 中的应用程序具有读写权限