Webhooks: подписанные payloads и надёжные повторы

Backend2026-10-20TryQuickToolBox

Вы только что интегрировали сторонний платёжный шлюз или CI/CD-сервис, и теперь вам нужны уведомления в реальном времени. Webhooks — это решение, но без должной безопасности и надёжности они могут стать источником разочарования. Злоумышленники могут подделывать запросы, а сетевые сбои — приводить к пропуску событий. В этом руководстве мы разберём, как защитить webhooks с помощью подписанных payloads и реализовать надёжные механизмы повторов.

Что такое webhooks?

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

Однако webhooks создают две проблемы: подлинность (убедиться, что запрос пришёл от ожидаемого отправителя) и надёжность (убедиться, что вы не пропустили события).

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

Подписанный payload использует секрет, общий для отправителя и получателя, для создания криптографической подписи. Отправитель включает эту подпись в заголовок, а получатель проверяет её, чтобы подтвердить целостность и происхождение payload.

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

HMAC (Hash-based Message Authentication Code) — стандартный подход. Отправитель вычисляет HMAC над телом запроса с использованием общего секрета и включает его в заголовок, например X-Signature. Получатель пересчитывает HMAC и сравнивает.

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

function generateSignature(payload, secret) {
  return crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(payload))
    .digest('hex');
}

// На принимающей стороне проверяем:
function verifySignature(payload, secret, receivedSignature) {
  const expected = generateSignature(payload, secret);
  // Используйте сравнение, устойчивое к тайминговым атакам
  return crypto.timingSafeEqual(
    Buffer.from(expected, 'hex'),
    Buffer.from(receivedSignature, 'hex')
  );
}

Ключевые моменты:

Дополнительные меры безопасности

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

Сети ненадёжны. Webhook может не доставиться из-за таймаутов, ошибок сервера или временных сбоев. Надёжная стратегия повторов обеспечивает итоговую доставку, не перегружая вашу систему или отправителя.

Лучшие практики повторов

  1. Экспоненциальная задержка: увеличивайте интервал между повторами (например, 1с, 2с, 4с, 8с...).
  2. Максимальный лимит повторов: ограничьте число попыток (например, 5), чтобы избежать бесконечных циклов.
  3. Dead-letter queue: после исчерпания повторов сохраните неудачные события для ручной проверки.
  4. Идемпотентность: убедитесь, что обработка одного и того же события несколько раз не вызывает дублирующих побочных эффектов.

Идемпотентность на практике

Включайте уникальный ID события в payload. На стороне получателя отслеживайте обработанные ID (в базе данных или кэше) и игнорируйте дубликаты. Например:

// Псевдокод для идемпотентной обработки
if (eventStore.exists(event.id)) {
  return 200; // Уже обработано
}
// Обработка события...
eventStore.save(event.id);

Корректная обработка сбоев

Быстро отвечайте статусом 2xx, чтобы подтвердить получение. Если обработка занимает время, поставьте событие в очередь и обрабатывайте асинхронно. Возвращайте 5xx только для временных ошибок, требующих повтора; для постоянных ошибок (например, неверный payload) возвращайте 4xx, чтобы предотвратить бесполезные повторы.

Сравнение: push vs. poll

Аспект Webhooks (Push) Polling
Задержка Почти реальное время Зависит от интервала
Эффективность Отправка только при событиях Постоянные запросы
Сложность Требует логики повторов/безопасности Проще, но расточительно

Тестирование реализации webhook

Используйте инструменты вроде ngrok, чтобы открыть локальный сервер и имитировать доставку webhooks. Проверяйте валидацию подписи и поведение повторов, намеренно вызывая сбои запросов.

FAQ

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

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

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

Универсального числа нет, но обычно используют 3–5 повторов с экспоненциальной задержкой. После этого зафиксируйте сбой для ручной проверки.

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

Технически да, но это крайне небезопасно. Всегда используйте HTTPS, чтобы предотвратить прослушивание и атаки man-in-the-middle.

Готовы проверить payloads webhooks? Используйте наш JSON formatter, чтобы быстро отформатировать и провалидировать JSON payloads.