我正在尝试使用Python对Amazon的SimpleDB服务进行API调用。例如,我正在使用最简单的请求ListDomains
。然而,无论我尝试什么,响应总是“我们计算的请求签名与您提供的签名不匹配。”
这是我正在签名的字符串(根据documentation here):
GET
https://sdb.amazonaws.com/
/
AWSAccessKeyId=<redacted>&Action=ListDomains&SignatureMethod=HmacSHA1&SignatureVersion=2&Timestamp=2011-04-19T18%3A50%3A43&Version=2009-04-15
我使用以下代码对其进行签名:
import base64,hashlib,hmac,time
# Sign the request
signature = hmac.new(
key=AWS_SECRET_ACCESS_KEY,
msg=string_to_sign,
digestmod=hashlib.sha1).digest()
# Base64 encode the signature
signature = base64.encodestring( signature )
我已经用HmacSHA256和HmacSHA1进行了尝试。似乎没什么用。我做错了什么?
答案 0 :(得分:2)
一个关键问题是您必须对所有HTTP参数值进行正确的URL编码。
以下文档已从SimpleDB文档中消失,但可以在SQS文档中找到,并且仍与SimpleDB非常相关:
不要对任何网址进行网址编码 RFC 3986无保留的字符 定义
这些未保留的字符是A-Z, a-z,0-9,连字符( - ),下划线(_ ),句号(。)和波浪号(〜)。
百分比编码所有其他字符 %XY,其中X和Y是十六进制 字符0-9和大写字母A-F。
百分比编码扩展的UTF-8 %XY%ZA形式的字符
百分比将空格字符编码为 %20(而不是+,作为常见编码 计划。)。
您会注意到在python-simpledb
模块中,由Roger链接,他们在形成请求时遵循这些规则:
def escape(s):
return urllib.quote(s, safe='-_~')
def urlencode(d):
if isinstance(d, dict):
d = d.iteritems()
return '&'.join(['%s=%s' % (escape(k), escape(v)) for k, v in d])
答案 1 :(得分:0)
我不会重新发明轮子 - 有几个python simpledb库,如;
如果没有别的,他们的签名代码应该澄清你的错误,但是说真的,使用现有的维护API,它会让你的生活更轻松。