Skip to main content
Hver anmodning, vi sender til din server — webhook-leveringer og kald af værktøjsendepunkter — indeholder en HMAC-SHA256-signatur i headeren X-ThunderPhone-Signature. Få verificeringen korrekt én gang, og brug den samme hjælpefunktion i alle handlere.

Algoritmen

  1. Læs den anmodningsbody — de præcise bytes, vi POSTede til dig.
  2. Beregn hmac_sha256(secret, body).hexdigest().
  3. Sammenlign i konstant tid med X-ThunderPhone-Signature. (En naiv strengsammenligning lækker tidsoplysninger.)
Vi signerer præcis de bytes, vi sender, så verificering af den rå body virker altid. Disse bytes er også payloadets kanoniske JSON-serialisering — nøgler sorteret alfabetisk, kompakte separatorer (, og : uden mellemrum), UTF-8. Det giver dig en anden, fuldt ækvivalent metode, når dit framework kun eksponerer parset JSON: serialiser kanonisk igen, og beregn HMAC over det.
Foretræk den rå body — det er ét trin mindre og undgår særheder ved JSON-tals round-tripping i nogle sprog.

Hvilken hemmelighed?

Gem hemmeligheden i din secret manager eller miljøvariabel — commit den aldrig.

Referenceimplementeringer

Alle fire verificerer den rå anmodningsbody:

Framework-specifik opsætning

Verificering af værktøjskald

Når agenten kalder et af dine funktionsværktøjer direkte (værktøjet har et endpoint), indeholder anmodningen to ThunderPhone-headere sammen med dine konfigurerede endpoint.headers:
  • X-ThunderPhone-Call-ID — det numeriske id for det aktive opkald.
  • X-ThunderPhone-Signature — HMAC-SHA256 med din webhookhemmelighed på organisationsniveau som nøgle, baseret på de nøjagtige bytes i anmodningens body.
Den samme verify()-hjælpefunktion fungerer uændret, med to detaljer:
  1. GET / DELETE-værktøjer har ingen body. Argumenter sendes som forespørgselsparametre, og signaturen beregnes over den tomme bytestreng — altså verify(b"", sig, secret) (Python) eller verify(Buffer.alloc(0), sig, secret) (Node). Hash ikke forespørgselsstrengen.
  2. Organisationer uden en konfigureret ældre webhook har ingen organisationshemmelighed. I så fald indeholder værktøjskald kun X-ThunderPhone-Call-ID og ingen signaturheader. Konfigurer den ældre webhook (PUT /v1/webhook) for at få en signeringshemmelighed, eller godkend værktøjskald med din egen header via endpoint.headers.
Værktøjsafsendelse i webhook-tilstand (værktøjer uden et endpoint, leveret til din organisationswebhook som telephony.tool / web.tool) er en almindelig signeret webhook — standardopsætningen ovenfor gælder. Se Funktionsværktøjer for begge anmodningsformater.

Almindelige faldgruber

At parse brødteksten og dumpe den igen med dit JSON-biblioteks standardindstillinger (mellemrum efter , / :, nøgler i indsættelsesrækkefølge) giver forskellige bytes og ødelægger HMAC’en. Verificer den rå brødtekst — eller hvis du skal serialisere igen, så match vores kanoniske format nøjagtigt: sorterede nøgler, kompakte separatorer, UTF-8.
Express’ express.json()-middleware bruger brødtekststrømmen, og du mister de rå bytes. Brug specifikt express.raw() på webhook-ruten, eller buffer den rå brødtekst i en pre-middleware. Det samme gælder NestJS / Koa — se deres dokumentation om “raw body”.
expected === signature i JS eller expected == signature i Python er sammenligninger med variabel timing. Brug henholdsvis crypto.timingSafeEqual eller hmac.compare_digest. Ydelsesforskellen er nul.
Direkte kald til værktøjsendepunkter signeres med webhook-secreten på organisationsniveau (GET /v1/webhook) — ikke med en secret pr. endepunkt fra /v1/developer/webhook-endpoints. Genbrug den samme verify()- funktion, men sørg for at give den organisations-secreten på værktøjsruter.
For værktøjsmetoder uden brødtekst dækker signaturen den tomme bytestreng, så der bevares én universel opskrift: HMAC den rå request body, uanset hvad den er. Hashing af URL’en eller querystrengen vil aldrig matche.
At returnere 200 ved mislykket verificering gør handleren til et mål for replay-angreb. Svar altid med en ikke-2xx-status, hvis verificeringen mislykkes.

Næste trin

Webhooks-oversigt

Leveringssemantik, genforsøg, kilde-IP’er.

Webhook-endepunkter

Administrer flere URL’er, rotér secrets.

Funktionsværktøjer

De to veje til værktøjskald og deres request-formater.

Værktøjsintegrationer

Byg en komplet værktøjsunderstøttet integration fra start til slut.