Post 使用 /1.1/statuses/update.json 在自己的 Twitter 帐户上发推文失败,无法对您进行身份验证

Post tweets on own Twitter account using /1.1/statuses/update.json fails, Could not authenticate you

亲爱的

我已经投入了相当多的时间来尝试 post 从我的网站向我自己的 Twitter 用户帐户发送推文,而不使用任何现成的解决方案。 该网站在 app.twitter.com 上获得 read/write 访问权限,我已重新生成所有密钥。

我正在关注有关端点 "POST /1.1/statuses/update.json"

的 Twitter API 说明

我已经仔细检查了我所有的对象,但仍然收到

response       =--- !ruby/object:Net::HTTPUnauthorized
http_version: '1.1'
code: '401'
message: Authorization Required
header:
  connection:
  - close
  content-length:
  - '89'
  content-type:
  - application/json; charset=utf-8
  date:
  - Wed, 18 Oct 2017 15:28:19 GMT
  server:
  - tsa_o
  set-cookie:
  - personalization_id="v1_pxDMvL5ZrViFDcn8AfFemw=="; Expires=Fri, 18 Oct 2019 15:28:19
    UTC; Path=/; Domain=.twitter.com
  - guest_id=v1%3A150834049962807489; Expires=Fri, 18 Oct 2019 15:28:19 UTC; Path=/;
    Domain=.twitter.com
  strict-transport-security:
  - max-age=631138519
  x-connection-hash:
  - '05228a7a2026efc93a8a2d4b1a8c6460'
  x-response-time:
  - '142'
  x-tsa-request-body-time:
  - '1'
body: '{"errors":[{"code":32,"message":"Could not authenticate you."}]}'
read: true
uri:
decode_content: true
socket:
body_exist: true

我想从我的网站发送一个简单的 "Hello" 到我的 Twitter 帐户,并仔细检查了下面将展示的所有部分。

此外,使用我的 Twitter 帐户在我的网站上使用相同的逻辑对我进行身份验证。所以我知道授权(3 条腿)可以正常工作。

对于 post 使用我的 rails 应用程序发送推文,我都尝试过 1) post 使用我的应用程序的消费者和访问令牌对发送推文,而无需执行所有授权步骤以及 2) 引导自己使用 Twitter 明确重新授权我的网站 post 这条推文。这两种情况都会导致错误 401。一切正常,除了实际的推文步骤。

非常感谢任何帮助。请注意,我对使用 gem 不感兴趣,并且已经通读了相关的 API 文档。

这是我的 post 请求的所有成分:

Parameter String:    
include_entities=true&
oauth_consumer_key=Xffffffffffffffffffffffff&
oauth_nonce=1vGbvxCqsfGi47L7ecpRnwA33fEojFoy6J2hkRpa8&
oauth_signature_method=HMAC-SHA1&
oauth_timestamp=1508340584&
oauth_token=4444444444-GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG&
oauth_version=1.0&
status=Hello

signature base string:
POST&
https%3A%2F%2Fapi.twitter.com%2F1.1%2Fstatuses%2Fupdate.json&
include_entities%3Dtrue%26
oauth_consumer_key%3DXffffffffffffffffffffffff%26
oauth_nonce%3D1vGbvxCqsfGi47L7ecpRnwA33fEojFoy6J2hkRpa8%26
oauth_signature_method%3DHMAC-SHA1%26
oauth_timestamp%3D1508340584%26
oauth_token%3D4444444444-GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG%26
oauth_version%3D1.0%26
status%3DHello

signing key:
W6SzwsKSXwFpl8tb0UNJFoCTW6crf6p3JaS8GipJMErofZVLAA&ENxK6XHG8h2EI7dOeSL0fABJzqnzs7FhP6QirBbXvd0br

signature:
0zx68mHx/SxhHkoRpaqZmO8iC2s=

header string:
OAuth oauth_consumer_key="Xffffffffffffffffffffffff", 
oauth_nonce="1vGbvxCqsfGi47L7ecpRnwA33fEojFoy6J2hkRpa8", 
oauth_signature="0zx68mHx%2FSxhHkoRpaqZmO8iC2s%3D", 
oauth_signature_method="HMAC-SHA1", 
oauth_timestamp="1508340584", 
oauth_token="4444444444-GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG", 
oauth_version="1.0"


POST REQUEST
request        =--- !ruby/object:Net::HTTP::Post
method: POST
request_has_body: true
response_has_body: true
uri:
path: "/1.1/statuses/update.json?include_entities=true"
decode_content: true
header:
  content-type:
  - application/x-www-form-urlencoded
  authorization:
  - OAuth oauth_consumer_key="Xffffffffffffffffffffffff", oauth_nonce="1vGbvxCqsfGi47L7ecpRnwA33fEojFoy6J2hkRpa8",
    oauth_signature="0zx68mHx%2FSxhHkoRpaqZmO8iC2s%3D", oauth_signature_method="HMAC-SHA1",
    oauth_timestamp="1508340584", oauth_token="4444444444-GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG",
    oauth_version="1.0"
  host:
  - api.twitter.com
  accept-encoding:
  - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
  accept:
  - "*/*"
  user-agent:
  - Ruby
body: '{"status":"Hello"}'
body_stream:
body_data:

我终于让它工作了。存在几个问题。没有签名和授权 headers。相反,问题存在于所使用的时间戳中,它没有正确同步,也没有像 Twitter 所期望的那样在格林威治标准时间。我将我的系统时钟与 time.google.com 同步,这部分就完成了。现在,还有一个关于 header 的问题也需要排序,这与 Twitter 自己的文档仅讨论在签名基本字符串的上下文中排序相反。我发现扩展 header 也需要排序。扩展是因为它包含推文本身,这不是签名计算的一部分。一旦这部分建立在发布推文中就成功了