Webhooks: подписанные payload и стратегии повтора

Backend2026-11-10TryQuickToolBox

Почему webhooks дают сбои и как это исправить

Вы только что интегрировали webhook платёжного провайдера для обновления статусов заказов в вашем приложении. В тестах всё работает, но в продакшене некоторые события не приходят или, что хуже, вы получаете дубликаты. Без надлежащих мер защиты webhooks могут стать источником скрытых сбоев и уязвимостей.

Webhooks — это HTTP-колбэки, запускаемые событиями, но, в отличие от типичных вызовов API, они работают по принципу push и асинхронно. Это создаёт две основные проблемы: проверка подлинности и обеспечение доставки. В этом руководстве мы рассмотрим обе с помощью подписанных payload и продуманных повторных попыток.

Что такое webhooks?

Webhook — это определяемый пользователем HTTP-колбэк. Когда в исходной системе происходит событие (например, новый платёж), она отправляет HTTP POST-запрос на указанный вами URL с данными события. Это позволяет реагировать в реальном времени без опроса.

Типичные сценарии использования включают уведомления о платежах, триггеры CI/CD и интеграции с чатами. Но поскольку webhooks передаются через публичный интернет, они уязвимы к подделке и потере.

Защита webhooks с помощью подписанных payload

Как узнать, что webhook действительно пришёл от вашего провайдера? Подписание payload общим секретом обеспечивает целостность и подлинность.

Как работают HMAC-подписи

Провайдер вычисляет HMAC (например, SHA-256) тела запроса с использованием секретного ключа и отправляет подпись в заголовке (например, X-Signature). Ваш сервер пересчитывает HMAC и сравнивает его с помощью сравнения за постоянное время, чтобы предотвратить атаки по времени.

// Пример на Node.js: проверка подписи webhook
const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
  const hmac = crypto.createHmac('sha256', secret);
  hmac.update(payload);
  const digest = hmac.digest('hex');
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(digest));
}

Лучшие практики:

Реализация надёжных повторных попыток

Даже с подписями сетевые проблемы или простои могут привести к сбою доставки webhook. Провайдеры обычно повторяют попытки с экспоненциальной задержкой, но вы также должны обрабатывать повторы на своей стороне.

Идемпотентность: ключ к безопасным повторам

Повторы могут привести к дублирующей обработке. Используйте ключи идемпотентности (часто включаются в payload или в заголовок), чтобы гарантировать, что каждое событие обрабатывается ровно один раз. Сохраняйте идентификаторы обработанных событий и игнорируйте дубликаты.

// Пример: идемпотентный обработчик webhook
const processedEvents = new Set();

app.post('/webhook', (req, res) => {
  const eventId = req.body.id;
  if (processedEvents.has(eventId)) {
    return res.status(200).send('Already processed');
  }
  // process event...
  processedEvents.add(eventId);
  res.status(200).send('OK');
});

Стратегия повторов на стороне получателя

Если обработка не удалась, ответьте статусом 5xx, чтобы инициировать повторную попытку провайдера. Для временных ошибок вы также можете реализовать собственную очередь повторов с задержкой.

СценарийОтветДействие
Успех200 OKБез повтора
Ошибка валидации400 Bad RequestБез повтора (исправьте payload)
Ошибка сервера500 Internal Server ErrorПровайдер повторяет
Ограничение скорости429 Too Many RequestsПровайдер повторяет после задержки

Мониторинг и отладка webhooks

Записывайте все входящие запросы webhook с заголовками и payload (скрывая конфиденциальные данные). Используйте инструмент, такой как JSON Formatter, для форматирования payload и облегчения проверки. Настройте оповещения о неудачных доставках и отслеживайте количество повторов.

FAQ

Что такое подписанный payload webhook?

Подписанный payload включает криптографическую подпись (обычно HMAC), которая подтверждает, что запрос пришёл из доверенного источника и не был изменён.

Сколько раз следует повторять неудачный webhook?

Большинство провайдеров повторяют 3–5 раз с экспоненциальной задержкой. Как получатель, отвечайте соответствующими кодами состояния и позволяйте провайдеру обрабатывать повторы.

Можно ли использовать webhooks без HTTPS?

Нет — HTTPS необходим для шифрования payload и предотвращения атак «человек посередине». Никогда не принимайте webhooks по простому HTTP.

Готовы проверять и отлаживать payload webhooks? Попробуйте наш бесплатный JSON Formatter, чтобы мгновенно форматировать и проверять данные JSON.