X-ThunderPhone-Signature. Configurați verificarea corect o singură dată și utilizați același ajutor în fiecare handler.
Algoritmul
- Citiți corpul brut al solicitării — octeții exacți pe care vi i-am trimis prin POST.
- Calculați
hmac_sha256(secret, body).hexdigest(). - Comparați în timp constant cu
X-ThunderPhone-Signature. (Compararea naivă a șirurilor dezvăluie informații de temporizare.)
, și : fără spații), UTF-8. Astfel aveți o a doua metodă, complet
echivalentă, atunci când frameworkul dumneavoastră expune doar JSON analizat:
reserializați canonic și calculați HMAC pentru acesta.
Care secret?
Stocați secretul în managerul dumneavoastră de secrete sau într-o variabilă de mediu — nu îl comiteți niciodată.
Implementări de referință
Toate cele patru verifică corpul brut al solicitării:Configurare specifică frameworkului
Verificarea apelurilor de instrumente
Când agentul invocă direct unul dintre instrumentele de funcții (instrumentul are unendpoint), solicitarea include două antete ThunderPhone pe lângă
endpoint.headers configurat:
X-ThunderPhone-Call-ID— ID-ul numeric al apelului în desfășurare.X-ThunderPhone-Signature— HMAC-SHA256, cu cheia reprezentată de secretul webhook la nivel de organizație, calculat peste octeții exacți ai corpului solicitării.
verify() funcționează fără modificări, cu două particularități:
- Instrumentele
GET/DELETEnu au corp. Argumentele sunt transmise ca parametri de interogare, iar semnătura este calculată peste șirul de octeți gol — deciverify(b"", sig, secret)(Python) sauverify(Buffer.alloc(0), sig, secret)(Node). Nu calculați hash-ul șirului de interogare. - Organizațiile fără un webhook moștenit configurat nu au un secret de organizație.
În acest caz, apelurile de instrumente includ doar
X-ThunderPhone-Call-IDși niciun antet de semnătură. Configurați webhookul moștenit (PUT /v1/webhook) pentru a obține un secret de semnare sau autentificați apelurile de instrumente cu propriul antet prinendpoint.headers.
endpoint,
livrate către webhookul organizației dumneavoastră ca telephony.tool / web.tool)
este un webhook semnat obișnuit — se aplică procedura standard de mai sus. Consultați
Instrumente de funcții pentru ambele forme de solicitare.
Capcane frecvente
Reserializarea cu formatarea implicită
Reserializarea cu formatarea implicită
Analizarea corpului și serializarea lui din nou cu setările implicite
ale bibliotecii JSON (spații după
, / :, chei în ordinea inserării) produce
octeți diferiți și invalidează HMAC-ul. Verificați corpul brut — sau, dacă
trebuie să îl reserializați, respectați exact forma noastră canonică: chei
sortate, separatori compacți, UTF-8.Frameworkul analizează automat JSON-ul
Frameworkul analizează automat JSON-ul
Middleware-ul
express.json() din Express consumă fluxul corpului
și pierdeți octeții bruti. Utilizați express.raw() specific pe ruta
webhookului sau stocați corpul brut într-un pre-middleware.
La fel și pentru NestJS / Koa — consultați documentația lor despre „raw body”.Comparație nesigură din perspectiva timpului
Comparație nesigură din perspectiva timpului
expected === signature în JS sau expected == signature în
Python sunt comparații cu durată variabilă. Utilizați crypto.timingSafeEqual
sau, respectiv, hmac.compare_digest. Diferența de performanță
este nulă.Secret greșit pentru endpointurile de instrumente
Secret greșit pentru endpointurile de instrumente
Apelurile directe către endpointurile de instrumente sunt semnate cu secretul
webhook la nivel de organizație (
GET /v1/webhook) — nu cu un secret per-endpoint
din /v1/developer/webhook-endpoints. Reutilizați aceeași funcție verify(),
dar asigurați-vă că îi transmiteți secretul organizației pe rutele instrumentelor.Hash-uirea șirului de interogare pentru instrumentele GET/DELETE
Hash-uirea șirului de interogare pentru instrumentele GET/DELETE
Pentru metodele de instrumente fără corp, semnătura acoperă șirul gol de
octeți, păstrând o singură rețetă universală: calculați HMAC-ul pentru corpul brut
al solicitării, indiferent care este acesta. Hash-uirea URL-ului sau a șirului de interogare nu se va potrivi niciodată.
Nereturnarea codului 401 la nepotrivire
Nereturnarea codului 401 la nepotrivire
Returnarea codului 200 când verificarea eșuează transformă handlerul într-o
țintă pentru reluarea solicitărilor. Răspundeți întotdeauna cu un cod diferit de 2xx dacă verificarea eșuează.
Pașii următori
Prezentare generală a webhookurilor
Semantica livrării, reîncercări, IP-uri sursă.
Endpointuri webhook
Gestionați mai multe URL-uri, rotiți secretele.
Instrumente pentru funcții
Cele două căi de invocare a instrumentelor și formatele solicitărilor lor.
Integrări de instrumente
Creați o integrare completă bazată pe instrumente, de la un capăt la altul.