Вебхуки: подписанные данные и стратегии повтора

Backend2026-11-07TryQuickToolBox

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

Вебхуки — это HTTP-обратные вызовы, инициируемые событиями, которые передают данные в ваше приложение в режиме реального времени. В отличие от опроса, они эффективны и почти мгновенны. Но они создают проблемы: как узнать, что запрос действительно пришел от ожидаемого отправителя, и как обрабатывать сбои, когда получатель временно недоступен? В этой статье рассматриваются подписанные данные и механизмы повтора, даются практические шаблоны для создания устойчивых интеграций вебхуков.

Почему вебхукам нужны подписи

Конечные точки вебхуков — это общедоступные URL-адреса. Без проверки любой может отправлять поддельные запросы на вашу конечную точку, потенциально вызывая несанкционированные действия или повреждение данных. Подписанные данные решают эту проблему, добавляя криптографическую подпись к каждому запросу, что позволяет вам проверить личность отправителя и убедиться, что данные не были изменены.

Большинство провайдеров используют HMAC (код аутентификации сообщения на основе хэша) с общим секретом. Отправитель вычисляет хэш данных с использованием секрета и включает его в заголовок. Вы пересчитываете хэш на своей стороне и сравниваете. Если они совпадают, запрос является законным.

Реализация проверки HMAC

Давайте рассмотрим типичную реализацию на Node.js. Предположим, провайдер отправляет подпись в заголовке X-Signature, вычисленную как HMAC-SHA256 от необработанного тела запроса с использованием вашего секрета.

const crypto = require('crypto');
const express = require('express');
const app = express();

// Use raw body parser to preserve exact payload
app.use(express.raw({ type: 'application/json' }));

app.post('/webhook', (req, res) => {
  const signature = req.headers['x-signature'];
  const secret = process.env.WEBHOOK_SECRET;
  
  const expected = crypto
    .createHmac('sha256', secret)
    .update(req.body)
    .digest('hex');
  
  if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
    return res.status(401).send('Invalid signature');
  }
  
  // Process the event
  const event = JSON.parse(req.body);
  // ... handle event
  
  res.status(200).send('OK');
});

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

Разработка стратегии повтора

Даже с подписями доставка может не удаться из-за проблем с сетью, простоя сервера или тайм-аутов. Надежная стратегия повтора обеспечивает eventual delivery, не перегружая вашу систему или отправителя.

1. Быстро подтверждайте, обрабатывайте асинхронно

Ваша конечная точка вебхука должна как можно быстрее ответить статусом 2xx, в идеале в течение нескольких секунд. Если обработка занимает больше времени, поставьте событие в очередь для фоновой обработки. Это предотвращает тайм-ауты и позволяет отправителю считать доставку успешной.

2. Реализуйте экспоненциальную задержку с джиттером

Когда доставка не удалась (ответ не 2xx или тайм-аут), отправитель должен повторить попытку с увеличивающимися задержками. Экспоненциальная задержка (например, 1 с, 2 с, 4 с, 8 с...) предотвращает перегрузку вашей конечной точки. Добавление случайного джиттера избегает проблемы «стада» при одновременном сбое многих вебхуков.

Пример графика повторов:

После максимального количества повторов (например, 5) отправитель должен остановиться и уведомить вас (например, по электронной почте или через панель управления).

3. Обрабатывайте дубликаты с помощью идемпотентности

Повторы могут вызвать дублирующиеся доставки. Ваша конечная точка должна быть идемпотентной: обработка одного и того же события несколько раз должна иметь тот же эффект, что и однократная обработка. Используйте уникальный идентификатор события из данных и сохраните его. Перед обработкой проверьте, не встречался ли этот идентификатор; если да, верните 200 без повторной обработки.

Распространенные подходы:

Сравнение: подписанные данные и другие меры безопасности

Метод Плюсы Минусы
Подпись HMAC Проверяет подлинность и целостность; без сохранения состояния Требует управления общим секретом
Белый список IP Просто реализовать IP-адреса могут меняться; не подходит для динамических сред
Базовая аутентификация Легко добавить Учетные данные отправляются в каждом запросе; менее безопасно
JWT в заголовке Может включать утверждения и срок действия Накладные расходы на выпуск/проверку токена

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

Лучшие практики для потребителей вебхуков

Лучшие практики для производителей вебхуков

Тестирование вашей реализации вебхука

Используйте такие инструменты, как ngrok, чтобы открыть ваш локальный сервер и имитировать доставку вебхуков. Напишите модульные тесты для проверки подписи и логики идемпотентности. Для нагрузочного тестирования рассмотрите инструменты, которые могут отправлять подписанные запросы в масштабе.

При отладке проверяйте необработанные данные и заголовки. Форматировщик JSON может помочь визуализировать структуру данных. Попробуйте наш JSON Formatter, чтобы быстро отформатировать и проверить данные вебхука.

Часто задаваемые вопросы

Что такое подписанные данные вебхука?

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

Сколько раз следует повторять вебхук?

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

Могу ли я использовать JWT вместо HMAC для подписей вебхуков?

Да, JWT может работать, но это добавляет сложности (выпуск токена, срок действия). HMAC проще и достаточно для большинства случаев. Выбирайте в зависимости от вашей существующей инфраструктуры и требований.

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