为什么用POST请求获取Twitter API的应用程序授权的Bearer Token时,返回400 Bad request错误?

4

我正在尝试按照这里的指示获取Twitter API应用程序的仅限应用程序身份验证的Bearer Token:

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

然而,每次我使用curl进行描述中的请求时,都会返回“400 Bad request”状态和空响应体。有人能看出我做错了什么吗?
我正在尝试使用curl,认为这将使正确的请求更容易。首先:
$ export CONSUMER_KEY="[...]"
$ export CONSUMER_SECRET="[...]"

显然,我省略了那些值,但那些是我从https://apps.twitter.com/获取的,在我创建的应用程序的“Keys and Access Tokens”选项卡中 - 它们来自此处的两个已编辑部分:

redacted screenshot of apps.twitter.com ID keys and access tokens tab

然后我使用以下内容发起请求:
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错误请求和空白正文,即使发送到服务器的内容看起来完全符合文档要求。为了展示此问题,以下是来自命令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个回答

6

好的,常常发生的是,在我发布问题之前,我已经解决了问题,但答案可能对其他人有帮助,所以我还是会在这里发布一下。

当你将$CONSUMER_KEY:$CONSUMER_SECRET进行base64编码并将其发送到Authorization头中时,Twitter文档所描述的内容只是HTTP基本身份验证

正如维基百科所说:

生成的字符串使用RFC2045-MIME变体的Base64进行编码,没有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'

感谢Hans Z这个问题的评论,让我找对了方向!


1
感谢提供示例。我遇到了错误#99,因为基本身份验证标头格式不正确 - 通过将我的调试与“curl -v -u”进行比较,发现了差异。 - Nakilon

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