X-ThunderPhone-Signature. Один раз правильно налаштуйте перевірку та
підключіть той самий допоміжний засіб до кожного обробника.
Алгоритм
- Прочитайте необроблене тіло запиту — точні байти, які ми надіслали вам методом POST.
- Обчисліть
hmac_sha256(secret, body).hexdigest(). - Порівняйте в сталий час зі значенням
X-ThunderPhone-Signature. (Наївне порівняння рядків розкриває інформацію про час виконання.)
, і : без пробілів), UTF-8. Це дає вам другий, цілком
еквівалентний спосіб, якщо ваш фреймворк надає лише розібраний JSON:
повторно серіалізуйте його канонічно та обчисліть HMAC.
Який секрет?
Зберігайте секрет у менеджері секретів або змінній середовища — ніколи не додавайте його до комітів.
Довідкові реалізації
Усі чотири перевіряють необроблене тіло запиту:Налаштування для конкретних фреймворків
Перевірка викликів інструментів
Коли агент безпосередньо викликає один із ваших функціональних інструментів (інструмент маєendpoint), запит містить два заголовки ThunderPhone разом із
налаштованими вами endpoint.headers:
X-ThunderPhone-Call-ID— числовий ідентифікатор активного дзвінка.X-ThunderPhone-Signature— HMAC-SHA256 із ключем у вигляді вашого секрету webhook на рівні організації, обчислений для точних байтів тіла запиту.
verify() працює без змін, але є два нюанси:
- Інструменти
GET/DELETEне мають тіла. Аргументи передаються як параметри запиту, а підпис обчислюється для порожнього рядка байтів — тобтоverify(b"", sig, secret)(Python) абоverify(Buffer.alloc(0), sig, secret)(Node). Не хешуйте рядок запиту. - Організації без налаштованого застарілого webhook не мають секрету організації. У
такому разі виклики інструментів містять лише
X-ThunderPhone-Call-IDі не мають заголовка підпису. Налаштуйте застарілий webhook (PUT /v1/webhook), щоб отримати секрет для підписування, або автентифікуйте виклики інструментів власним заголовком черезendpoint.headers.
endpoint, що доставляються
до webhook вашої організації як telephony.tool / web.tool) є звичайним
підписаним webhook — застосовуйте стандартний підхід вище. Див. розділ
Функціональні інструменти для обох форматів запитів.
Поширені помилки
Повторна серіалізація зі стандартним форматуванням
Повторна серіалізація зі стандартним форматуванням
Аналіз тіла запиту та повторне виведення за допомогою стандартних
налаштувань вашої JSON-бібліотеки (пробіли після
, / :, ключі в порядку вставлення) створює
інші байти та порушує HMAC. Перевіряйте необроблене тіло запиту — або, якщо
потрібно повторно серіалізувати його, точно дотримуйтеся нашої канонічної форми: відсортовані
ключі, компактні роздільники, UTF-8.Фреймворк автоматично аналізує JSON
Фреймворк автоматично аналізує JSON
Проміжне ПЗ Express
express.json() споживає потік тіла запиту,
і ви втрачаєте необроблені байти. Використовуйте express.raw() безпосередньо для маршруту
вебхука або буферизуйте необроблене тіло в попередньому проміжному ПЗ.
Те саме стосується NestJS / Koa — перегляньте їхню документацію щодо «raw body».Порівняння, небезпечне щодо часу виконання
Порівняння, небезпечне щодо часу виконання
expected === signature у JS або expected == signature у
Python — це порівняння зі змінним часом виконання. Використовуйте crypto.timingSafeEqual
або hmac.compare_digest відповідно. Різниця в продуктивності
відсутня.Неправильний секрет для кінцевих точок інструментів
Неправильний секрет для кінцевих точок інструментів
Прямі виклики кінцевих точок інструментів підписуються за допомогою секрету вебхука
на рівні організації (
GET /v1/webhook) — а не секрету для кожної кінцевої точки
з /v1/developer/webhook-endpoints. Повторно використовуйте ту саму функцію verify(),
але переконайтеся, що передаєте їй секрет організації в маршрутах інструментів.Хешування рядка запиту для інструментів GET/DELETE
Хешування рядка запиту для інструментів GET/DELETE
Для методів інструментів без тіла запиту підпис охоплює порожній рядок
байтів, зберігаючи один універсальний підхід: обчислюйте HMAC для необробленого тіла запиту,
яким би воно не було. Хеш URL або рядка запиту ніколи не збігатиметься.
Не повертати 401 у разі невідповідності
Не повертати 401 у разі невідповідності
Повернення 200 у разі невдалої перевірки робить обробник ціллю для повторного відтворення
запитів. Завжди повертайте статус не з діапазону 2xx, якщо перевірка не пройшла.
Наступні кроки
Огляд вебхуків
Семантика доставки, повторні спроби, IP-адреси джерел.
Кінцеві точки вебхуків
Керуйте кількома URL-адресами, змінюйте секрети.
Function Tools
Два шляхи виклику інструментів і формати їхніх запитів.
Інтеграції інструментів
Створіть повну інтеграцію на основі інструментів від початку до кінця.