为什么POST请求为Twitter的API返回400 Bad请求的仅应用程序auth获取持有者令牌?

时间:2016-04-24 13:34:42

标签: curl twitter oauth-2.0

我按照以下说明尝试按照说明获取Twitter API的仅限应用的身份验证的承载令牌:

https://dev.twitter.com/oauth/application-only

然而,每当我用卷曲来描述那里描述的请求时,我得到一个" 400 Bad request"返回状态和空响应正文。谁能看到我做错了什么?

我尝试使用curl认为这样可以更轻松地提出正确的请求。第一:

$ export CONSUMER_KEY="[...]"
$ export CONSUMER_SECRET="[...]"

显然我已经在那里省略了价值观,但那些是我在{"钥匙和访问令牌"上{{}}}获得的价值观。我创建的应用的标签 - 他们来自这里的两个编辑部分:

https://apps.twitter.com/

然后我发出请求:

curl --trace-ascii curl-trace \
    -X POST \
    --data 'grant_type=client_credentials' \
    -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" \
    -H "User-Agent: YNR Twitter ID mapper v0.0.1" \
    -H "Authorization: Basic $(echo -n "$CONSUMER_KEY:$CONSUMER_SECRET" | base64)" \
    'https://api.twitter.com/oauth2/token'

然而,即使发送到服务器的内容完全符合文档所要求的内容,这也会一直返回400 Bad请求和空主体。为了显示这一点,来自命令的curl-trace文件的相关输出是:

== Info: Hostname was NOT found in DNS cache
== Info:   Trying 104.244.42.194...
== Info: Connected to api.twitter.com (104.244.42.194) port 443 (#0)
[... elided SSL connection details ...]
0000: POST /oauth2/token HTTP/1.1
001d: Host: api.twitter.com
0034: Accept: */*
0041: Content-Type: application/x-www-form-urlencoded;charset=UTF-8
0080: User-Agent: YNR Twitter ID mapper v0.0.1
00aa: Authorization: Basic [...]
00ea: [...]
012a: Content-Length: 29
013e: 
=> Send data, 29 bytes (0x1d)
0000: grant_type=client_credentials
== Info: upload completely sent off: 29 out of 29 bytes
== Info: HTTP 1.0, assume close after body
<= Recv header, 26 bytes (0x1a)
0000: HTTP/1.0 400 Bad Request
<= Recv header, 19 bytes (0x13)
0000: content-length: 0
<= Recv header, 37 bytes (0x25)
0000: date: Sun, 24 Apr 2016 12:55:59 GMT
<= Recv header, 15 bytes (0xf)
0000: server: tsa_f
<= Recv header, 53 bytes (0x35)
0000: x-connection-hash: [...]
<= Recv header, 2 bytes (0x2)
0000: 
== Info: Closing connection 0
== Info: SSLv3, TLS alert, Client hello (1):
=> Send SSL data, 2 bytes (0x2)
0000: ..

我为什么这不起作用感到困惑!

1 个答案:

答案 0 :(得分:6)

(好吧,经常发生我在发布问题之前弄清楚了什么是错的,但答案可能对其他人有帮助,所以无论如何我都会在这里发布。)

{base}编码$CONSUMER_KEY:$CONSUMER_SECRET并在Authorization标题中发送的部分中redacted screenshot of apps.twitter.com ID keys and access tokens tab描述的内容仅为the Twitter docs

正如维基百科页面所说:

  

使用Base64的RFC2045-MIME变体对结果字符串进行编码,但不限于76个字符/行。

(我的重点)。当我用:

构造字符串时
echo -n "$CONSUMER_KEY:$CONSUMER_SECRET" | base64

...在输出中包含换行符(0a)以打破长行,正如该引言所解释的那样,在编码用于HTTP基本访问身份验证的字符串时,您不需要。您可以使用-w 0抑制换行,如下所示:

echo -n "$CONSUMER_KEY:$CONSUMER_SECRET" | base64 -w 0

所以我尝试的命令的工作版本是:

curl --trace-ascii curl-trace \
    -X POST \
    --data 'grant_type=client_credentials' \
    -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" \
    -H "User-Agent: YNR Twitter ID mapper v0.0.1" \
    -H "Authorization: Basic $(echo -n "$CONSUMER_KEY:$CONSUMER_SECRET" | base64 -w 0)" \
    --compressed \
    'https://api.twitter.com/oauth2/token'

更简单的版本

使用curl选项让-u为您执行HTTP基本身份验证更容易,而不是让自己陷入base64。适用于我的curl命令的最简单版本是:

curl -u "$CONSUMER_KEY:$CONSUMER_SECRET" \
    --compressed \
    --data 'grant_type=client_credentials' \
    'https://api.twitter.com/oauth2/token'

(感谢HTTP basic authenticationHans Z的评论让我在这里走上正轨!)