Подписание запросов и меток времени
У Amazon есть удобный инструмент для тестирования запросов и подтверждения того, что вы правильно подписываете запросы, которые они называют "блокнотом". Вы вручаете ему неподписанный запрос, вводите свои данные для аутентификации, нажимаете "Отправить", и он выплевывает подписанный запрос. Либо он, либо мой код не работает, и логика подсказывает, что это мой код, но ничего в этом нет смысла. Может быть, кто-то здесь может увидеть то, что я не.
Если я вручу блокноту неподписанный запрос, как
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.
Если я вручную un-url-кодировать отметку времени, чтобы 2017-07-16T15:14:09.000Z
тогда, кажется, пройти это, только потерпеть неудачу с ужасом SignatureDoesNotMatch
,
НО
Если я создаю свое собственное подписанное сообщение, используя эту строку запроса из вышеуказанного URL-адреса со знаком и метку времени в кодировке URL, сигнатуры совпадают! Это означает, что их бэкэнд использует временную метку в кодировке URL для вычисления подписи, но любой мой запрос с меткой времени, закодированной в URL или нет, выдает ошибку "это не iso8601". Все, что делает URL-кодирование, заменяет %3A
за :
- не сложный процесс.
Я подтвердил, что языком сервера, на котором он работает, является utf-8, и что я использую application/x-www-form-urlencoded; charset=utf-8
как тип содержимого запросов, а также подтвердил, что системные часы синхронизируются с авторитетным сервером ntp.
Надеюсь, кто-то видел это или что-то подобное раньше.
1 ответ
Клиент Drakma автоматически кодирует параметры url, и получается, что время было закодировано дважды. Он также кодирует параметры, даже если вы передаете их не как список параметров, а непосредственно в URI. Чтобы сохранить URI без изменений, вы должны использовать :preserve-uri t
, как объяснено в документации:
Если preserve-uri не равен NIL, данный uri не будет обработан. Это означает, что URI будет отправлен как есть на удаленный сервер, и клиент должен убедиться, что все параметры закодированы правильно. Обратите внимание, что если этот параметр задан, а запрос не является POST с типом содержимого "multipart/form-data", параметры не будут использоваться.