Curl 为什么POST请求仅为Twitter的应用程序身份验证获取承载令牌';s API返回400错误请求?

Curl 为什么POST请求仅为Twitter的应用程序身份验证获取承载令牌';s API返回400错误请求?,curl,twitter,oauth-2.0,Curl,Twitter,Oauth 2.0,我正在尝试按照以下说明获取用于Twitter API的仅应用程序身份验证的承载令牌,如下所示: 然而,每次我用curl发出上面描述的请求时,我都会返回一个“400错误请求”状态和一个空的响应主体。有人能看出我做错了什么吗 我正在尝试使用curl这样做,我认为这样可以更容易地提出正确的请求。第一: $ export CONSUMER_KEY="[...]" $ export CONSUMER_SECRET="[...]" 显然,我已经省略了其中的值,但这些是我从我创建的应用程序的“密钥和访问令

我正在尝试按照以下说明获取用于Twitter API的仅应用程序身份验证的承载令牌,如下所示:

然而,每次我用curl发出上面描述的请求时,我都会返回一个“400错误请求”状态和一个空的响应主体。有人能看出我做错了什么吗

我正在尝试使用
curl
这样做,我认为这样可以更容易地提出正确的请求。第一:

$ export CONSUMER_KEY="[...]"
$ export CONSUMER_SECRET="[...]"
显然,我已经省略了其中的值,但这些是我从我创建的应用程序的“密钥和访问令牌”选项卡上获得的值-它们来自这里的两个编辑部分:

然后,我提出以下请求:

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: ..
==信息:在DNS缓存中找不到主机名
==信息:正在尝试104.244.42.194。。。
==信息:连接到api.twitter.com(104.244.42.194)端口443(#0)
[…省略的SSL连接详细信息…]
0000:POST/oauth2/token HTTP/1.1
001d:主机:api.twitter.com
0034:接受:*/*
0041:内容类型:application/x-www-form-urlencoded;字符集=UTF-8
0080:用户代理:YNR Twitter ID映射器v0.0.1
00aa:授权:基本[…]
00ea:[…]
012a:内容长度:29
013e:
=>发送数据,29字节(0x1d)
0000:授予\类型=客户端\凭据
==信息:上传已完全发送:29个字节中有29个
==信息:HTTP 1.0,假设正文后关闭
(好的,正如经常发生的那样,我在发布问题之前找出了问题的症结所在,但答案可能会对其他人有所帮助,所以我还是将其发布在这里。)

在base64编码
$CONSUMER\u KEY:$CONSUMER\u SECRET
并将其发送到
授权
头中的部分中,所描述的内容仅限于此

但正如维基百科页面所说:

生成的字符串使用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'

(感谢的评论,让我在这里走上了正确的道路!)

谢谢您的示例。我出现了错误#99,因为基本身份验证头的格式不正确——通过将我的调试与
curl-v-u