Коротко
Вебхук это сообщение, которое сервис сам отправляет на ваш адрес, когда происходит событие. Чтобы доверять такому сообщению, нужно проверять его подпись.
Иногда не вы спрашиваете сервис, а сервис сам сообщает вам новость. Это и есть вебхук. Здесь мы разберём идею, отличие от обычного запроса и безопасность. Если вы ещё не знаете, что такое API, начните с этого.
Что такое вебхук
Вебхук это обратный звонок от сервиса. Когда случается событие, сервис отправляет запрос на ваш адрес с данными о событии.
В обычном запросе инициатор это вы. В вебхуке инициатор это сервис. Это удобно, чтобы узнавать новости сразу, а не опрашивать сервер снова и снова.
Что такое событие
Событие это что то важное на стороне сервиса, например новый платёж или готовый результат. Именно событие запускает отправку вебхука вам.
Чем вебхук отличается от запроса
При обычном вызове ваша программа сама идёт за ответом. С этим вы уже знакомы по материалу про устройство запроса к API.
Вебхук работает наоборот. Вы заранее даёте сервису свой адрес, и он шлёт туда сообщения сам, когда нужно. Поэтому у вас должен быть открытый адрес, который принимает входящие запросы.
- Запрос: вы спрашиваете, сервер отвечает.
- Вебхук: сервис сам шлёт вам данные.
- Для вебхука нужен открытый адрес у вас.
Безопасность и подпись
Главный риск в том, что чужой может прислать поддельное сообщение на ваш адрес. Поэтому важно проверять, что запрос действительно от сервиса.
Для этого используют подпись. Сервис подписывает сообщение секретом, а вы проверяете подпись на своей стороне. Сам секрет это чувствительные данные, как и личная и секретная информация.
- Сервис добавляет подпись к сообщению.
- Вы вычисляете подпись тем же секретом.
- Если подписи совпали, сообщению можно верить.
Почему подпись важнее адреса
Адрес отправителя легко подделать, поэтому ему нельзя верить на слово. Только совпадение подписи доказывает, что сообщение настоящее.
Совет. Если подпись не совпала, сразу отклоняйте сообщение. Не обрабатывайте данные, в источнике которых вы не уверены.
Как проверить подпись по шагам
Идею проверки можно показать как обычный текст. Секрет тут берётся из окружения, а не из кода:
import os, hmac, hashlib
secret = os.environ.get("WEBHOOK_SECRET")
expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
# сравните expected с подписью из заголовка запроса
Точный алгоритм и имя заголовка смотрите в документации сервиса, они могут отличаться. Если подписи не совпали, сообщение нужно отклонить.
- Прочитайте секрет из переменной окружения.
- Вычислите подпись по телу запроса.
- Сравните её с подписью из заголовка.
- Отклоните запрос, если подписи разные.
Практика
Принимать вебхуки удобно небольшим веб-приложением с отдельным маршрутом для входящих сообщений. Простой пример эндпоинта мы показали в материале про приложение на Flask с AI.
Точный способ проверки подписи смотрите в официальной документации сервиса, потому что алгоритм и имя заголовка зависят от конкретной платформы. Общий обзор темы есть в разделе про API.
Отвечайте сервису быстро
Сервис ждёт короткий ответ, что сообщение принято. Тяжёлую работу делайте после, чтобы вебхук не повисал и не повторялся зря.
Что часто ломается
Самая опасная ошибка это принимать любые сообщения без проверки подписи. Тогда любой может прислать поддельные данные, и приложение им поверит.
Вторая ошибка это хранить секрет подписи прямо в коде, откуда он легко утекает. Чтобы этого избежать, всегда проверяйте подпись, держите секрет в окружении и ведите логи событий. И не доверяйте адресу отправителя на слово, ведь его легко подделать.
- Не принимайте сообщения без проверки подписи.
- Не храните секрет подписи в открытом коде.
- Не доверяйте адресу отправителя на слово.
- Не отключайте логи входящих событий.
Запрос против вебхука
| Свойство | Обычный запрос | Вебхук |
|---|---|---|
| Кто начинает | Вы | Сервис |
| Когда приходит | По вашему вызову | При событии |
| Что нужно | Ключ доступа | Открытый адрес и проверка подписи |
Важность шагов защиты (простая иллюстрация)
Как приходит вебхук
Случилось событие
На стороне сервиса что-то произошло.
Сервис шлёт запрос
Отправляет данные на ваш адрес.
Вы проверяете подпись
Сверяете её своим секретом.
Принимаете данные
Если подпись верна, обрабатываете.
Чеклист
- Завести отдельный адрес для вебхуков.
- Хранить секрет подписи безопасно.
- Проверять подпись каждого сообщения.
- Отклонять сообщения с неверной подписью.
- Сверять детали проверки с документацией.
- Вести логи входящих событий.
- Читать секрет из переменной окружения.
Частые ошибки
- Принимать любые сообщения без проверки.
- Хранить секрет подписи в открытом коде.
- Доверять адресу отправителя на слово.
- Не вести логи входящих событий.
- Использовать один секрет для всех сервисов.
Частые вопросы
В обычном запросе вы сами идёте за ответом. В вебхуке сервис сам шлёт вам сообщение, когда происходит событие.
Чтобы убедиться, что сообщение пришло от настоящего сервиса, а не от постороннего. Подпись подтверждает источник.
В официальной документации сервиса. Там описано, как именно вычислять и сверять подпись.
В переменной окружения или в защищённом хранилище, а не в коде. Так секрет не попадёт в репозиторий.
Отклоните такое сообщение и не обрабатывайте его. Это защищает приложение от поддельных данных.
Да, сервису нужно куда то слать сообщения. Поэтому у вас должен быть открытый адрес, который принимает входящие запросы.
Источники
Мы опираемся на официальную документацию. Цены и состав моделей могут меняться, проверяйте важные факты по первоисточникам.