LLMTOKENAPI

Webhook для AI API: подпись, повторы и безопасность

Практическая схема безопасного webhook для AI API: raw body, HMAC SHA-256, timestamp, защита от повторов, очередь и ротация секрета.

31 августа 2026 г.5 мин чтенияОбновлено 31 августа 2026 г.
Подписанный пакет данных проходит проверочный шлюз, а повтор блокируется

Webhook для AI API нужно принимать как недоверенный внешний запрос: проверить HMAC-подпись по исходному телу, ограничить допустимый возраст события и обработать уникальный event ID только один раз. Такая схема защищает асинхронные map, crawl и исследовательские задания от подмены, повторной доставки и двойного запуска бизнес-логики.

Зачем webhook, если статус можно опрашивать

Долгая операция не должна удерживать пользовательское HTTP-соединение. Клиент создаёт задание, получает идентификатор и продолжает работу. Когда результат готов, сервис отправляет событие на заранее заданный URL. Это уменьшает число запросов статуса и позволяет сразу продолжить внутренний процесс: сохранить результат, обновить карточку или поставить следующий шаг в очередь.

Polling всё равно полезен как резервный путь. Webhook сообщает о событии, но не обязан быть единственным источником истины. Если доставка задержалась или ваш endpoint был недоступен, приложение может получить состояние через GET /v1/jobs/{id} либо прочитать журнал доставок зарегистрированного endpoint.

В LLMTOKENAPI для простого map или crawl можно передать webhookUrl. Для нескольких типов задач удобнее создать постоянный webhook endpoint и подписать его только на нужные события, например job.completed и job.failed. Актуальные маршруты и scopes перечислены в документации API.

Сначала сохраните секрет и сырой body

Секрет webhook возвращается при создании endpoint и должен храниться так же внимательно, как API-ключ. Не записывайте его в репозиторий, браузерный код или обычные логи. При компрометации перевыпустите секрет и обновите принимающую сторону.

Для проверки подписи нужен именно исходный набор байтов HTTP-тела. Если сначала разобрать JSON, а потом сериализовать объект заново, изменятся пробелы или порядок полей, и корректная подпись перестанет совпадать. Поэтому обработчик должен сначала прочитать raw body, проверить запрос и только затем выполнять JSON.parse.

Руководство GitHub по проверке webhook использует тот же базовый принцип: вычислить HMAC от полученного тела с секретом и сравнить результат безопасным способом. Для LLMTOKENAPI подписываемая строка имеет форму timestamp.eventId.body, а служебные значения приходят в заголовках:

  • x-llmtokenapi-event-id — стабильный идентификатор события;
  • x-llmtokenapi-timestamp — время создания подписи;
  • x-llmtokenapi-signature — подпись HMAC SHA-256 с версией v1.

Проверяйте подпись до разбора события

Надёжный обработчик выполняет проверки в фиксированном порядке:

  1. Убеждается, что все три заголовка присутствуют и имеют ожидаемый формат.
  2. Проверяет, что timestamp попадает в небольшое допустимое окно относительно серверного времени.
  3. Собирает строку timestamp.eventId.rawBody без преобразования тела.
  4. Вычисляет HMAC SHA-256 с сохранённым секретом.
  5. Сравнивает подписи функцией постоянного времени.
  6. Проверяет event ID в хранилище обработанных событий.
  7. Только после этого разбирает JSON и запускает бизнес-логику.

Обычное сравнение строк через === не подходит для криптографической проверки. Используйте timingSafeEqual в Node.js или эквивалент вашей платформы. Перед сравнением убедитесь, что буферы одинаковой длины, иначе многие реализации выбросят исключение.

Защититесь от повторной доставки

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

Храните eventId в таблице с уникальным индексом. В одной транзакции попробуйте зафиксировать ID и выполнить изменение состояния. Если запись уже существует, верните успешный ответ без повторной работы. Такой подход превращает повторную доставку в нормальный сценарий, а не в инцидент.

Проверка возраста подписи решает другую задачу: не позволяет бесконечно воспроизводить старый корректный запрос. Практическое окно зависит от вашей очереди и сетевой задержки; выбирайте его явно и следите за синхронизацией времени на сервере. Сочетание timestamp и уникального event ID защищает лучше, чем любой из этих механизмов по отдельности.

Отвечайте быстро, тяжёлую работу выполняйте в очереди

Webhook endpoint должен проверить запрос, надёжно сохранить событие и быстро вернуть код 2xx. Извлечение большого результата, отправку писем или обновление поискового индекса лучше передать внутреннему worker. Иначе принимающая сторона может превысить таймаут, а отправитель начнёт повторять уже выполняющуюся работу.

Разделите статусы «событие принято» и «бизнес-операция завершена». Первый означает, что payload сохранён и больше не потеряется. Второй обновляется worker после фактической обработки. Для диагностики сохраняйте event ID, тип события, время получения, результат проверки и внутренний request ID, но не секрет и не чувствительное содержимое пользовательских данных.

Подготовьте endpoint к ошибкам и ротации

Перед production проверьте положительный и отрицательный сценарии. Корректная подпись должна приниматься; изменённое тело, старый timestamp и неверная подпись — отклоняться. Два запроса с одним event ID должны менять состояние только один раз. Временно недоступная база должна приводить к повторяемой ошибке, а не к потере события.

Постоянный webhook endpoint в LLMTOKENAPI можно протестировать, перевыпустить его секрет, посмотреть доставки и повторить конкретную неудачную доставку. Эти операции требуют отдельных scopes webhooks:read и webhooks:write, поэтому ключ для управления webhook не нужно использовать в обычном пользовательском трафике.

Итоговый webhook для AI API состоит не из одного публичного URL. Это проверка raw body, HMAC SHA-256, короткое окно времени, уникальность event ID, быстрая фиксация события и фоновая обработка. С такой схемой повторная доставка становится безопасной, а асинхронные задания — наблюдаемыми и предсказуемыми.

Webhook для AI API: подпись и защита от повторов | LLMTOKENAPI