X-ThunderPhone-Signature. Poprawnie zaimplementuj weryfikację raz, a następnie
użyj tego samego pomocnika w każdym handlerze.
Algorytm
- Odczytaj surowe ciało żądania — dokładne bajty, które wysłaliśmy.
- Oblicz
hmac_sha256(secret, body).hexdigest(). - Porównaj w stałym czasie z
X-ThunderPhone-Signature. (Naiwne porównanie ciągów ujawnia informacje o czasie.)
, i : bez spacji), UTF-8. Daje to drugi, w pełni
równoważny sposób, gdy framework udostępnia wyłącznie sparsowany JSON:
ponownie serializuj kanonicznie i oblicz HMAC dla wyniku.
Który sekret?
Przechowuj sekret w menedżerze sekretów lub zmiennej środowiskowej — nigdy nie commituj go.
Implementacje referencyjne
Wszystkie cztery weryfikują surowe ciało żądania:Integracja specyficzna dla frameworka
Weryfikowanie wywołań narzędzi
Gdy agent wywołuje bezpośrednio jedno z Twoich narzędzi funkcyjnych (narzędzie maendpoint), żądanie zawiera dwa nagłówki ThunderPhone wraz z
skonfigurowanymi przez Ciebie nagłówkami endpoint.headers:
X-ThunderPhone-Call-ID— numeryczny identyfikator trwającego połączenia.X-ThunderPhone-Signature— HMAC-SHA256 z kluczem w postaci sekretu webhooka na poziomie organizacji, obliczony na podstawie dokładnych bajtów treści żądania.
verify() działa bez zmian, z dwoma niuansami:
- Narzędzia
GET/DELETEnie mają treści. Argumenty są przekazywane jako parametry zapytania, a podpis jest obliczany na podstawie pustego ciągu bajtów — więc użyjverify(b"", sig, secret)(Python) lubverify(Buffer.alloc(0), sig, secret)(Node). Nie haszuj ciągu zapytania. - Organizacje bez skonfigurowanego starszego webhooka nie mają sekretu organizacji. W takim przypadku wywołania narzędzi zawierają tylko
X-ThunderPhone-Call-IDi nie zawierają nagłówka podpisu. Skonfiguruj starszy webhook (PUT /v1/webhook), aby uzyskać sekret podpisywania, lub uwierzytelniaj wywołania narzędzi własnym nagłówkiem za pomocąendpoint.headers.
endpoint, dostarczane
do webhooka organizacji jako telephony.tool / web.tool) jest zwykłym
podpisanym webhookiem — obowiązuje standardowa procedura opisana powyżej. Zobacz
Narzędzia funkcyjne, aby poznać oba formaty żądań.
Typowe pułapki
Ponowna serializacja z domyślnym formatowaniem
Ponowna serializacja z domyślnym formatowaniem
Przetworzenie treści i ponowne zapisanie jej za pomocą biblioteki JSON z
ustawieniami domyślnymi (spacje po
, / :, klucze w kolejności wstawiania) powoduje
powstanie innych bajtów i unieważnia HMAC. Zweryfikuj surową treść — lub jeśli
musisz ją ponownie serializować, dokładnie dopasuj naszą formę kanoniczną: posortowane
klucze, zwarte separatory, UTF-8.Framework automatycznie przetwarza JSON
Framework automatycznie przetwarza JSON
Middleware
express.json() w Express zużywa strumień treści
i tracisz surowe bajty. Użyj express.raw() konkretnie dla trasy webhooka
albo buforuj surową treść w pre-middleware.
Tak samo jest w NestJS / Koa — sprawdź ich dokumentację dotyczącą „raw body”.Porównanie nieodporne na ataki czasowe
Porównanie nieodporne na ataki czasowe
expected === signature w JS lub expected == signature w
Pythonie to porównania o zmiennym czasie wykonania. Użyj odpowiednio crypto.timingSafeEqual
lub hmac.compare_digest. Różnica w wydajności
jest pomijalna.Nieprawidłowy sekret dla endpointów narzędzi
Nieprawidłowy sekret dla endpointów narzędzi
Bezpośrednie wywołania endpointów narzędzi są podpisywane za pomocą sekretu
webhooka na poziomie organizacji (
GET /v1/webhook) — a nie za pomocą sekretu przypisanego do endpointu
z /v1/developer/webhook-endpoints. Użyj ponownie tej samej funkcji verify(),
ale upewnij się, że dla tras narzędzi przekazujesz do niej sekret organizacji.Haszowanie ciągu zapytania w narzędziach GET/DELETE
Haszowanie ciągu zapytania w narzędziach GET/DELETE
W przypadku metod narzędzi bez treści podpis obejmuje pusty ciąg
bajtów, co pozwala zachować jedną uniwersalną metodę: wykonaj HMAC na surowej treści żądania,
niezależnie od tego, jaka ona jest. Haszowanie adresu URL lub ciągu zapytania nigdy nie będzie zgodne.
Brak zwracania 401 przy niezgodności
Brak zwracania 401 przy niezgodności
Zwracanie 200 po nieudanej weryfikacji sprawia, że handler staje się celem
ataków typu replay. Zawsze zwracaj kod inny niż 2xx, jeśli weryfikacja się nie powiedzie.
Kolejne kroki
Przegląd webhooków
Semantyka dostarczania, ponowienia, źródłowe adresy IP.
Endpointy webhooków
Zarządzaj wieloma adresami URL, rotuj sekrety.
Narzędzia funkcji
Dwie ścieżki wywoływania narzędzi i formaty ich żądań.
Integracje narzędzi
Utwórz kompletną integrację opartą na narzędziach od początku do końca.