HMAC прошёл проверку после пересылки через Adal
Получение вебхуков от платёжной системы — тот случай, где «почти правильно» недостаточно.
Я использую Adal в продакшене для приёма вебхуков от платёжного сервиса. Запрос проходит через Adal Server и Adal CLI, а затем попадает в конечный обработчик — и его HMAC-подпись успешно проверяется. Это практическое подтверждение того, что подписанные данные доходят без изменений.
Такой вебхук может сообщать об успешной оплате, возврате, отмене или изменении статуса операции. Его важно не только получить, но и убедиться, что запрос действительно отправлен платёжным сервисом и не был изменён по пути. Для этого провайдеры обычно подписывают вебхуки с помощью HMAC.
На этой неделе обычная рабочая ситуация ещё раз показала мне, зачем я использую Adal в собственной продакшен-инфраструктуре.
Зачем Adal стоит между платёжным сервисом и обработчиком
Мой маршрут выглядит так:
Платёжный сервис → Adal Server → Adal CLI → обработчик вебхука
Adal здесь выполняет роль промежуточного слоя. Он принимает входящий запрос на постоянный публичный HTTPS URL, сохраняет его и передаёт через Adal CLI в закрытое окружение, где работает конечный обработчик.
Это даёт несколько практических преимуществ:
вебхук сначала надёжно принимается Adal;
- запрос и состояние его доставки можно увидеть в интерфейсе;
- при временной недоступности обработчика доставку можно повторить;
- для приёма вебхуков закрытому окружению не нужен публичный входящий адрес или открытый порт.
Для платёжных событий это особенно полезно. Если что-то пошло не так, у меня остаётся принятый Request, история попыток и возможность разобраться в проблеме без догадок по разрозненным логам.
Но у промежуточного слоя есть важное требование: он не должен незаметно менять данные, от которых зависит проверка подписи.
Что в этом маршруте проверяет HMAC
Конкретная схема зависит от платёжного сервиса. Как правило, отправитель вычисляет подпись на основе тела запроса и общего секрета; иногда в подписываемую строку также входят timestamp или другие поля. Получатель выполняет тот же расчёт и сравнивает результат с подписью из запроса.
Если изменить хотя бы один байт подписанного тела — например, преобразовать JSON, поменять пробелы или кодировку, — рассчитанная подпись уже не совпадёт. То же относится к другим значениям, если они участвуют в схеме подписи конкретного провайдера.
В моём случае проверка происходит не на стороне Adal, а в конечном обработчике, после прохождения всей цепочки:
получение → сохранение → передача через CLI → доставка → HMAC-проверка
И проверка проходит успешно.
Это значит, что данные, включённые платёжным сервисом в подпись, дошли до обработчика в том виде, в котором были отправлены. Adal не разобрал JSON и не собрал его заново, не изменил форматирование payload и не внёс скрытое преобразование, которое нарушило бы подпись.
Почему это важнее синтетического теста
Можно написать тест, отправить заранее подготовленное тело и сравнить результат. Такие тесты нужны, но реальный платёжный вебхук проверяет больше элементов сразу:
запрос сформирован внешней системой, которую я не контролирую;
- подпись рассчитана этой системой по её правилам;
- запрос принят публичным Adal Server;
- сохранён и передан через реальный продакшен-маршрут;
- конечное приложение независимо проверило подпись.
Успешный результат не основан на том, что Adal и тест используют одну и ту же заранее подготовленную строку. Это сквозная проверка на реальном трафике.
Важно сформулировать вывод точно: HMAC подтверждает неизменность тех частей запроса, которые входят в подпись конкретного провайдера. Он не доказывает побитовое равенство каждого элемента HTTP-соединения — например, транспортные заголовки могут формироваться заново при каждой передаче. Но для webhook payload и других подписанных значений это сильное и практически значимое подтверждение.
Продукт, которым я сам пользуюсь
Adal создавался вокруг простого принципа: доставка вебхуков должна быть прозрачной и предсказуемой, без скрытых преобразований.
В этом кейсе особенно приятно, что подтверждение приходит не из маркетингового текста. Я использую Adal для собственных продакшен-задач, вижу принятые запросы и историю доставки, могу повторить попытку при необходимости — а мой обработчик продолжает успешно проверять HMAC платёжного сервиса после прохождения запроса через Adal.
Именно так и должно работать промежуточное звено: давать надёжность и наблюдаемость, не становясь источником неожиданных изменений.