读取HTTP API docs。我的请求因签名错误而失败。从错误消息中,我可以看到我要签名的字符串是正确的,但是看起来我无法生成正确的HMAC-SHA1(严重地为什么仍要使用SHA1?)。
所以我决定尝试在同一文档中复制样本的签名。
[47] pry(main)> to_sign = "GET&%2F&AccessKeyId%3Dtestid&Action%3DDescribeRegions&Format%3DXML&SignatureMethod%3DHMAC-SHA1&SignatureNonce%3D3ee8c1b8-83d3-44af-a94f-4e0ad82fd6cf&SignatureVersion%3D1.0&Timestamp%3D2016-02-23T12%253A46%253A24Z&Version%3D2014-05-26"
[48] pry(main)> Base64.encode64 OpenSSL::HMAC.digest("sha1", "testsecret", to_sign)
=> "MLAxpXej4jJ7TL0smgWpOgynR7s=\n"
[49] pry(main)> Base64.encode64 OpenSSL::HMAC.digest("sha1", "testsecret&", to_sign)
=> "VyBL52idtt+oImX0NZC+2ngk15Q=\n"
[50] pry(main)> Base64.encode64 OpenSSL::HMAC.hexdigest("sha1", "testsecret&", to_sign)
=> "NTcyMDRiZTc2ODlkYjZkZmE4MjI2NWY0MzU5MGJlZGE3ODI0ZDc5NA==\n"
[51] pry(main)> Base64.encode64 OpenSSL::HMAC.hexdigest("sha1", "testsecret", to_sign)
=> "MzBiMDMxYTU3N2EzZTIzMjdiNGNiZDJjOWEwNWE5M2EwY2E3NDdiYg==\n"
[52] pry(main)> OpenSSL::HMAC.hexdigest("sha1", "testsecret&", to_sign)
=> "57204be7689db6dfa82265f43590beda7824d794"
[53] pry(main)> OpenSSL::HMAC.hexdigest("sha1", "testsecret", to_sign)
=> "30b031a577a3e2327b4cbd2c9a05a93a0ca747bb"
显然,这些都不匹配CT9X0VtwR86fNWSnsc6v8YGOjuE=
的示例签名。知道这里缺少什么吗?
更新:从Golang客户端工具中提取了tcpdump
,我看到它发出了一个POST
请求,例如:
POST /?AccessKeyId=**********&Action=DescribeRegions&Format=JSON&RegionId=cn-qingdao&Signature=aHZVpIMb0%2BFKdoWSIVaFJ7bd2LA%3D&SignatureMethod=HMAC-SHA1&SignatureNonce=c29a0e28964c470a8997aebca4848b57&SignatureType=&SignatureVersion=1.0&Timestamp=2018-07-16T19%3A46%3A33Z&Version=2014-05-26 HTTP/1.1
Host: ecs.aliyuncs.com
User-Agent: Aliyun-CLI-V3.0.3
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
x-sdk-client: golang/1.0.0
x-sdk-core-version: 0.0.1
x-sdk-invoke-type: common
Accept-Encoding: gzip
当我从上述请求中获取参数并生成签名时,它匹配。因此,我尝试了所有树:GET
,POST
(带有URL参数)和POST
(带有正文参数)。每次我遇到签名错误。如果我使用与golang工具完全相同的参数来重做请求,那么我将收到现时现用错误(如预期)。
答案 0 :(得分:1)
O(log(n))
而不是&
串联。
%26
require 'rubygems' require 'aliyun' $DEBUG = true options = { :access_key_id => "k", :access_key_secret => "s", :service => :ecs } service = Aliyun::Service.new options puts service.DescribeRegions({})
答案 1 :(得分:1)
最后成功了。在我的情况下,主要问题是我对签名参数进行了百分之二的编码,因此结果无效。对我最大的帮助是运行{% extends "base.html" %}
<h1>Django</h1>
{% block content %}
<h1>Django</h1>
{% endblock %}
cli实用程序并捕获流量,然后使用完全相同的参数运行查询以比较确切的查询字符串。
但是让我列出一些要点:
aliyun
字符&
既可以用作Format
,也可以用作json
JSON
,+
和*
的特殊编码规则似乎仅适用于签名字符串,而实际上并不适用于HTTP查询中的数据编码。我决定不使用@wanghq的包装器,因为它对我也不起作用disables certificate validation,但也许它将得到解决。我只是以为,一旦找出签名,查询就足够简单了,而附加的间接层是不值得的。尽管对我的签名有帮助,但对他的答案+1。
下面是发出简单请求的示例红宝石代码:
~
可以稍微简化一下代码,但决定使其与文档说明非常接近。
P.S。不知道为什么约翰删除了他的答案,但是在上面为任何寻找示例代码的python家伙留下了指向他网页的链接