1

亚马逊有一个方便的工具,用于测试请求并确认您正在正确签署请求,他们称之为“便签本”。你给它一个未签名的请求,输入你的身份验证信息,点击提交,它就会吐出一个签名的请求。要么是它,要么是我的代码坏了,逻辑表明这是我的代码,但这没有任何意义。也许这里有人可以看到我看不到的东西。

如果我将暂存器交给一个未签名的请求,例如

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.

如果我手动取消对时间戳进行 url 编码,2017-07-16T15:14:09.000Z那么它似乎已经过去了,只是以可怕的SignatureDoesNotMatch.

如果我使用上面签名 url 中的查询字符串和url 编码的时间戳制作自己的签名消息,则签名匹配!这意味着他们的后端使用 url 编码的时间戳来计算签名,但是我提出的任何带有时间戳的请求,无论是否是 url 编码的,都会给我“那不是 iso8601”错误。%3A所有 url-encoding 所做的只是替代:- 不是一个复杂的过程。

我已经确认正在运行的服务器的语言环境是 utf-8,并且我将application/x-www-form-urlencoded; charset=utf-8其用作请求的内容类型,并确认系统时钟与权威的 ntp 服务器同步。

希望有人以前看过这个或类似的东西。

4

1 回答 1

2

Drakma客户端自动对参数进行 url-encodes,它会将时间编码两次。即使您不将它们作为参数列表传递,而是直接在 uri 中传递,它也会对参数进行编码。为了保持 URI 不变,您必须使用:preserve-uri t,如文档中所述:

如果 preserve-uri 不是 NIL,则不会处理给定的 uri。这意味着 uri 将按原样发送到远程服务器,客户端有责任确保所有参数都正确编码。请注意,如果给定了此参数,并且请求不是内容类型为 `multipart/form-data' 的 POST,则不会使用参数。

于 2017-07-17T15:07:15.253 回答