亚马逊有一个方便的工具,用于测试请求并确认您正确签署请求,他们称之为“暂存器”。您将其交给未签名的请求,输入您的身份验证信息,点击提交,然后它会发出已签名的请求。要么它或我的代码坏了,逻辑表明它是我的代码,但没有任何关于这个是有道理的。也许这里的某个人可以看到我不是的东西。
如果我给暂挂簿提交了一份未签名的请求,例如
http://webservices.amazon.com/onca/xml?AWSAccessKeyId=ME&AssociateTag=ME&Keywords=bbq&Operation=ItemSearch&ResponseGroup=ItemAttributes&SearchIndex=All&Service=AWSECommerceService
我回来了
http://webservices.amazon.com/onca/xml?AWSAccessKeyId=ME&AssociateTag=ME&Keywords=bbq&Operation=ItemSearch&ResponseGroup=ItemAttributes&SearchIndex=All&Service=AWSECommerceService&Timestamp=2017-07-16T15%3A14%3A09.000Z&Signature=4oLDpXEdZ%2BEEPBOOPIMAROBOTiALFPPeICbs%3D
如果我向该URL发出请求(我是从AMZN的工具获得的),我得到了
Value 2017-07-16T15%3A14%3A09.000Z for parameter Timestamp is invalid. Reason: Must be in ISO8601 format.
如果我手动将时间戳解压缩编码为2017-07-16T15:14:09.000Z
,那么它似乎已经过去了,只会因为可怕的SignatureDoesNotMatch
失败。
BUT
如果我使用上面签名的网址中的查询字符串和网址编码的时间戳创建自己的签名邮件,则签名会匹配!这意味着他们的后端使用url编码的时间戳来计算签名,但是我的任何带有时间戳的请求,无论是否为url编码,都会给出“那不是iso8601”的错误。所有url编码都在用%3A
代替:
- 而不是一个复杂的过程。
我已经确认运行的服务器的语言环境是utf-8,我正在使用application/x-www-form-urlencoded; charset=utf-8
作为请求的内容类型,并确认系统时钟与权威的ntp服务器同步。
希望有人之前已经看过这个或类似的东西。
答案 0 :(得分:2)
Drakma客户端自动对参数进行url编码,并将时间编码两次。即使您不将它们作为参数列表传递,它也会对参数进行编码,但直接在uri中。为了保持URI不被修改,您必须使用:preserve-uri t
,如文档中所述:
如果preserve-uri不是NIL,则不会处理给定的uri。这意味着uri将按原样发送到远程服务器,客户端有责任确保所有参数都已正确编码。请注意,如果给出此参数,并且请求不是内容类型为“multipart / form-data”的POST,则不会使用参数。