#java #python #security #hash
Вопрос:
Я работаю над настройкой интеграции с сервисом под названием Printify. Я нахожусь в процессе настройки веб-крючков, и у меня есть последний шаг, с которым я сталкиваюсь с трудностями: безопасность с помощью хэш-кодов. Документация по API: https://developers.printify.com/#webhooks — — — > >Защита ваших веб-крючков.
Поток выглядит следующим образом:
- Создайте веб-хук через http api и передайте дополнительную подпись x-pfy-заголовка с секретным ключом и вызываемым URL-адресом, который будет прослушиваться моей системой.
- При вызове события webhook будет вызван этот вызываемый URL-адрес.
- Я должен проверить тело запроса, используя этот секретный ключ, чтобы убедиться, что это законный вызов от Printify.
Шаг 3-это то, где у меня возникают проблемы. Они приводят пример кода на Python:
import os
import hmac
def sha256hash(request):
hash = hmac.new(os.environ['SECRET_TOKEN'].encode('utf-8'),
request.data.encode('utf-8'),
'sha256')
return 'sha256=' hash.hexdigest()
def secure_compare(a, b):
return hmac.compare_digest(a, b)
print('%r' % secure_compare(request.headers['x-pfy-signature'],
sha256hash(request)))
Похоже, что я создаю некоторую закодированную строку, вводя тело запроса, полученное от Printify, вместе с секретным ключом, а затем проверяю, соответствует ли закодированная строка заголовку запроса x-pfy-подписи, которая будет такой же, как и исходная, которую я передал?
Может ли кто-нибудь проверить, что это правильно, и рассказать, как это сделать с помощью узла?
Ответ №1:
Вот решение NodeJS: https://bytethisstore.com/articles/pg/printify-webhooks-node-js
В документации на самом деле отсутствует шаг. Когда вы создаете секретный ключ, вы должны отправить его в качестве третьего параметра с именем «секрет» при создании веб-крючка. Это та часть, которая отсутствует в документации.
Поэтому, когда вы создаете веб-хук, вы отправляете:
{
"topic": "order:created",
"url": "{webhook_callback_url}",
"secret": "{secret_key}"
}
Затем, когда Printify отправляет данные на вашу конечную точку, они используют этот секретный ключ для хэширования ответа и отправляют этот хэш в качестве заголовка x-pfy-подписи.
Как и в их примере с python, вы должны сравнивать хэши, а не сам секретный ключ. Вам нужно хэшировать данные, отправленные на веб-крючок, с помощью секретного ключа, а затем сравнить свой хэш с отправленной подписью. Все так, как вы описали.
В PHP это намного проще, и именно эту функцию я использую для проверки подписи:
function validate_webhook($request, $signature): bool
{
$signature = str_replace('sha256=', '', $signature);
$hash = hash_hmac('sha256', $request, {secret_key});
return hash_equals($signature, $hash);
}
где $request
находится тело запроса и $signature
содержимое заголовка x-pfy-подписи.