webhooks
Подпись запросов
Как подписывать ваши POST-запросы вебхука с помощью HMAC-SHA256, чтобы Spectra их верифицировала.
Каждый POST на вебхук Spectra должен нести подпись HMAC-SHA256 тела. Неподписанные запросы или запросы с недействительной подписью отклоняются с 401 Unauthorized.
Подпись
X-Spectra-Signature: sha256=<hex>
X-Spectra-Timestamp: <unix-ms>
Подпись вычисляется по <timestamp>.<body> (разделено точкой):
import hmac, hashlib, time
secret = b"<your secret bytes>"
ts = str(int(time.time() * 1000))
body = '{"action":"buy","symbol":"BTCUSDT","qty":1}'
mac = hmac.new(secret, f"{ts}.{body}".encode(), hashlib.sha256).hexdigest()
headers = {
"X-Spectra-Signature": f"sha256={mac}",
"X-Spectra-Timestamp": ts,
"Content-Type": "application/json",
}
Зачем метка времени
Включение метки времени в подписанный payload привязывает сообщение к моменту. Перехваченное и воспроизведённое сообщение за пределами 5-минутного окна не проходит проверку — см. Защита от повторов.
Проверка на стороне сервера
Воркер Spectra:
- Читает
X-Spectra-Timestamp. Отклоняет, если отсутствует или старше 5 мин. - Читает
X-Spectra-Signature. Отклоняет, если отсутствует или повреждена. - Заново вычисляет HMAC по
<timestamp>.<body>с секретом. - Сравнивает с проверкой за постоянное время. Отклоняет при несовпадении.
- Валидирует схему тела (см. Схема payload).
- Отправляет брокеру.
Частые ошибки
- Подпись тела без префикса метки времени.
- Использование
==вместо сравнения за постоянное время на вашем собственном сервере (риск тайминг-атаки; не проблема Spectra, но стоит сделать правильно, если вы проксируете наш вебхук). - Отправка JSON с отличиями в пробелах от того, что было подписано — всегда подписывайте точные байты, которые вы отправляете POST.