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

Backend2026-10-31TryQuickToolBox

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

Что такое вебхуки?

Вебхуки — это определяемые пользователем HTTP-обратные вызовы. Когда в исходной системе происходит событие (например, новый коммит, успешный платеж), она отправляет HTTP POST-запрос на указанный вами URL. В отличие от опроса, вебхуки передают данные почти в реальном времени, снижая задержку и нагрузку на сервер. Однако эта модель push-уведомлений создает проблемы: проверка подлинности и обработка сбоев доставки.

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

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

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

Большинство сервисов используют HMAC-SHA256. Отправитель создает подпись, хешируя данные с помощью секретного ключа, и включает ее в заголовок (например, X-Signature). Получатель делает то же самое и сравнивает с помощью функции постоянного времени для предотвращения атак по времени.

Пошагово: проверка подписанных данных

  1. Извлеките подпись из заголовка (например, X-Signature).
  2. Получите исходное тело запроса в виде строки или буфера — не анализируйте его заранее, так как изменения форматирования нарушают подпись.
  3. Вычислите ожидаемую подпись с помощью HMAC-SHA256 с вашим секретным ключом.
  4. Сравните подписи с помощью функции сравнения постоянного времени.
  5. Отклоните запрос с HTTP 401, если они не совпадают.

Вот пример на Node.js с использованием Express:

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

app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
  const signature = req.headers['x-signature'];
  const secret = process.env.WEBHOOK_SECRET;
  const payload = req.body; // raw buffer

  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .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(payload);
  // ... handle event
  res.status(200).send('OK');
});

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

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

Даже с подписанными данными сетевые проблемы или простои сервера могут вызвать сбои доставки. Надежная стратегия повтора гарантирует, что события не будут потеряны. Ключевые соображения:

1. Быстрое подтверждение

Ответьте статусом 2xx, как только проверите подпись и поставите событие в очередь на обработку. Это предотвратит тайм-аут отправителя и ненужные повторные попытки.

2. Идемпотентность

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

3. Экспоненциальная задержка с джиттером

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

Типичное расписание повторов:

ПопыткаЗадержка
1Немедленно
21 минута
35 минут
430 минут
52 часа

4. Очередь недоставленных сообщений

После максимального числа повторов переместите событие в очередь недоставленных сообщений для ручной проверки. Это предотвращает бесконечные повторы и потерю данных.

5. Мониторинг и оповещения

Отслеживайте процент успешных доставок, задержку и причины сбоев. Настройте оповещения о всплесках сбоев, чтобы вовремя обнаруживать проблемы.

Распространенные ошибки и лучшие практики

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

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

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

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

Фиксированного числа нет; распространенная практика — от 3 до 10 повторов с экспоненциальной задержкой. После этого события часто отправляются в очередь недоставленных сообщений.

Можно ли использовать вебхуки без подписей?

Это возможно, но крайне не рекомендуется. Без подписей ваша конечная точка уязвима для поддельных запросов и утечек данных.

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