Twitter 1.1 OAuth authenticity_token_error(99)

9
我使用以下代码来获取Bearer令牌:
$token = base64_encode($client_id.':'.$client_sec);

$data = array ('grant_type' => 'client_credentials');
$data = http_build_query($data);

$header = array(
    'Authorization: Basic '.$token,
    'Content-type: application/x-www-form-urlencoded;charset=UTF-8',
    'Content-Length: ' . strlen($data)
);

$options = array(
    CURLOPT_HTTPHEADER => $header,
    CURLOPT_HEADER => false,
    CURLOPT_URL => 'https://api.twitter.com/oauth2/token',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POSTFIELDS => $data
);

$ch = curl_init();
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
curl_close($ch);
print_r($result);
exit;

但是一直输出:

{"errors":[{"label":"authenticity_token_error","code":99,"message":"无法验证您的凭据"}]}

我做错了什么?


1
很可能是凭据不正确,因此无法进行身份验证? - hakre
5个回答

19

在解决这个问题时,我发现问题出在我使用浏览器中已经登录 Twitter 帐户的高级Rest客户端进行调用 /oauth2/token。在退出 Twitter 并再次调用 API 后,它就正常工作了。

简短回答:确保在尝试请求Bearer令牌时没有已经登录到Twitter的活动会话。


你救了我的命。 - CarlosJavier
天哪....为什么?!?!我以为我的速率被限制了或者什么的。(谢谢你!) - WildJoe

6

我曾经为此苦苦挣扎,发现的答案似乎都没有什么帮助。错误信息的文档也不够清晰明了,只是简单地说“出了问题”。

我的问题是我使用了我找到的一堆代码拼凑而成的混搭程序,头部信息并没有被正确使用:

$headers = array(
    'Authorization' => 'Basic ' . base64_encode($appid . ':' . $secret), // WRONG!!!

    'Authorization: Basic ' . base64_encode($appid . ':' . $secret),     // Correct!
    'Content-Type: application/x-www-form-urlencoded;charset=UTF-8',     // Correct!
);

对我来说,问题在于授权头使用键值格式,而内容类型头不是。这破坏了授权头。
以下是一些与错误99相关的其他要检查的事项:
  1. 验证您的凭据是否正确并且已进行base64编码(请参见上文)
  2. 确保请求使用POST
  3. 确保设置了内容类型(请参见上文)
  4. 确保您将grant_type=client_credentials包含为一个post字段。
  5. 需要SSL,请确保正在使用它(https://)
  6. 尝试详细日志记录以帮助调试。它应该包括SSL证书信息、您的授权头和内容类型头。但是,这不会显示grant_type字段,只会显示头文件。
  7. 如果一切看起来都很正常,但仍然无法工作,那么您可能会受到速率限制。速率限制每15分钟重置一次。
当您最终获得访问令牌时,请确保缓存它以避免速率限制。我相信您每15分钟可以获得450个请求。如果您不缓存令牌,其中一半将用于获取访问令牌!

1
个人而言,我在编码的密钥和密码之前缺少了“Basic”。 - Jerome Mouneyrac

1

这里已经有一个被接受的答案,但是以防万一有人走到这篇文章并且有和我一样的问题...

Twitter文档参考 -> OAuth 2.0文档

误解 #1: 授权字符串是使用消费者密钥(也称为API密钥)和消费者秘密(也称为API秘密密钥)生成的。在developer.twitter.com的UI上显示这些凭据比apps.twitter.com不太明显。尽管是常见的RIF问题。

误解 #2: 这不是一个真正的误解,而是在对url连接的Consumer Key+":"+Consumer Secret进行base64编码时的实现错误。如果没有通过程序进行此操作,请确保在任何地方检查空格(特别是在:)周围的连接字符串中,您正在对其进行base64编码。

作为一点建议,Postman有一个很棒的工具,可以发起REST调用以检索OAuth2.0令牌(以及其他授权令牌)。当我尝试使用需要OAuth1.0令牌的API时,这对我非常有用。


0

Twitter OAuth 2.0 Bearer Token:

步骤1:编码消费者密钥和密钥
A - 将编码的消费者密钥、冒号字符“:”和编码的消费者密钥连接成一个字符串。
B - 对上一步骤中的字符串进行Base64编码。
示例函数:convertStringBase64("Api key" +":"+"Api key secret")
C- 这些步骤将生成“Authorization”

步骤2:获取Bearer令牌
URL: https://api.twitter.com/oauth2/token
请求必须是HTTP POST请求。
请求必须包括一个带有值为Basic <base64 encoded value from step 1>的Authorization头。
请求必须包括一个带有值为application/x-www-form-urlencoded;charset=UTF-8Content-Type头。
请求的正文必须是grant_type=client_credentials

示例请求(Authorization头已包装):

POST /oauth2/token HTTP/1.1
Host: api.twitter.com
User-Agent: My Twitter App v1.0.23
Authorization: Basic eHZ6MWV2RlM0d0VFUFRHRUZQSEJvZzpMOHFxOVBaeVJn
                     NmllS0dFS2hab2xHQzB2SldMdzhpRUo4OERSZHlPZw==
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 29
Accept-Encoding: gzip

grant_type=client_credentials

如果请求格式正确,服务器将会响应一个JSON编码的有效载荷:

示例响应:

HTTP/1.1 200 OK
Status: 200 OK
Content-Type: application/json; charset=utf-8
...
Content-Encoding: gzip
Content-Length: 140

{"token_type":"bearer","access_token":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAAAAAAAAAAAA%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"}

了解更多信息,请查看Twitter开发者API中的https://developer.twitter.com/en/docs/authentication/oauth-2-0/application-only


0

在解决这个问题的过程中,我终于想出了解决方案。Twitter实际上没有发送正确的消息,如果存在任何错误。

当我从curl发送请求时,它运行良好,但是通过代码时,我遇到了相同的错误{"errors":[{"label":"authenticity_token_error","code":99,"message":"Unable to verify your credentials"}]}

所以我发现,问题出在访问控制头上。设置这些头对我不起作用。

     xhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
     xhttp.setRequestHeader('Access-Control-Allow-Headers', '*');
     xhttp.setRequestHeader('Access-Control-Allow-Origin', '*')
     xhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest')

作为一种解决方法,我只是使用了这个URL来绕过对处理程序的CORS请求。
https://cors-anywhere.herokuapp.com/https://api.twitter.com/oauth2/token

在实际的URL之前添加了 "https://cors-anywhere.herokuapp.com/",然后它开始工作了。希望有人能遇到这个问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接