X-ThunderPhone-Signature हेडर में एक HMAC-SHA256 सिग्नेचर होता है। वेरिफिकेशन को एक बार सही करें और
उसी हेल्पर को हर हैंडलर में प्लग करें।
एल्गोरिदम
- रॉ रिक्वेस्ट बॉडी पढ़ें — वे सटीक बाइट्स जिन्हें हमने आपको POST किया था।
hmac_sha256(secret, body).hexdigest()कंप्यूट करें।X-ThunderPhone-Signatureके साथ कॉन्स्टेंट टाइम में तुलना करें। (साधारण स्ट्रिंग तुलना टाइमिंग जानकारी लीक करती है।)
, और :), UTF-8। इससे आपको दूसरा, पूरी तरह
समकक्ष तरीका मिलता है जब आपका फ्रेमवर्क केवल पार्स किया हुआ JSON एक्सपोज़ करता है:
कैनॉनिकली री-सीरियलाइज़ करें और उसका HMAC करें।
कौन-सा सीक्रेट?
सीक्रेट को अपने सीक्रेट मैनेजर या env var में स्टोर करें — इसे कभी commit न करें।
रेफरेंस इम्प्लीमेंटेशन
चारों रॉ रिक्वेस्ट बॉडी को वेरिफाई करते हैं:फ़्रेमवर्क-विशिष्ट वायरिंग
टूल कॉल सत्यापित करना
जब एजेंट आपके किसी फ़ंक्शन टूल को सीधे इनवोक करता है (टूल मेंendpoint होता है), तो अनुरोध में आपके कॉन्फ़िगर किए गए
endpoint.headers के साथ दो ThunderPhone हेडर होते हैं:
X-ThunderPhone-Call-ID— लाइव कॉल की न्यूमेरिक id।X-ThunderPhone-Signature— सटीक रिक्वेस्ट-बॉडी बाइट्स पर आपके org-level webhook secret से की गई HMAC-SHA256।
verify() हेल्पर बिना बदलाव के काम करता है, दो अंतर के साथ:
GET/DELETEटूल में कोई बॉडी नहीं होती। आर्ग्यूमेंट्स क्वेरी पैरामीटर्स के रूप में जाते हैं, और सिग्नेचर की गणना खाली बाइट स्ट्रिंग पर होती है — इसलिएverify(b"", sig, secret)(Python) याverify(Buffer.alloc(0), sig, secret)(Node) का उपयोग करें। क्वेरी स्ट्रिंग को हैश न करें।- जिन संगठनों में लेगेसी webhook कॉन्फ़िगर नहीं है, उनमें org secret नहीं होता।
उस स्थिति में टूल कॉल में केवल
X-ThunderPhone-Call-IDहोता है और कोई सिग्नेचर हेडर नहीं होता। साइनिंग secret पाने के लिए लेगेसी webhook (PUT /v1/webhook) कॉन्फ़िगर करें, याendpoint.headersके जरिए अपने हेडर से टूल कॉल को ऑथेंटिकेट करें।
endpoint के बिना टूल, जो आपके org webhook पर
telephony.tool / web.tool के रूप में डिलीवर होते हैं) एक सामान्य साइन किया
हुआ webhook है — ऊपर दी गई स्टैंडर्ड रेसिपी लागू होती है। दोनों रिक्वेस्ट
शेप के लिए फ़ंक्शन टूल्स देखें।
सामान्य समस्याएँ
डिफ़ॉल्ट फ़ॉर्मैटिंग के साथ दोबारा सीरियलाइज़ करना
डिफ़ॉल्ट फ़ॉर्मैटिंग के साथ दोबारा सीरियलाइज़ करना
बॉडी को पार्स करके अपनी JSON लाइब्रेरी की डिफ़ॉल्ट सेटिंग्स के साथ
दोबारा डंप करने पर (
, / : के बाद स्पेस, इंसर्शन-ऑर्डर किए गए कीज़) अलग
बाइट्स बनते हैं और HMAC टूट जाता है। रॉ बॉडी को वेरिफ़ाई करें — या यदि
आपको दोबारा सीरियलाइज़ करना ही है, तो हमारे कैनॉनिकल फ़ॉर्म से बिल्कुल मिलान करें: सॉर्ट किए गए
कीज़, कॉम्पैक्ट सेपरेटर्स, UTF-8।फ़्रेमवर्क JSON को अपने-आप पार्स करता है
फ़्रेमवर्क JSON को अपने-आप पार्स करता है
Express का
express.json() मिडलवेयर बॉडी स्ट्रीम को कंज़्यूम कर लेता है
और रॉ बाइट्स खो जाते हैं। वेबहुक रूट पर विशेष रूप से express.raw() का उपयोग करें,
या प्री-मिडलवेयर में रॉ बॉडी को बफ़र करें।
NestJS / Koa के लिए भी यही बात लागू होती है — उनके “raw body” डॉक्यूमेंटेशन देखें।टाइमिंग-असुरक्षित तुलना
टाइमिंग-असुरक्षित तुलना
JS में
expected === signature या
Python में expected == signature टाइमिंग-वेरिएबल तुलनाएँ हैं। क्रमशः crypto.timingSafeEqual
या hmac.compare_digest का उपयोग करें। परफ़ॉर्मेंस का अंतर
शून्य है।टूल एंडपॉइंट्स के लिए गलत सीक्रेट
टूल एंडपॉइंट्स के लिए गलत सीक्रेट
डायरेक्ट टूल-एंडपॉइंट कॉल्स पर संगठन-स्तरीय वेबहुक
सीक्रेट (
GET /v1/webhook) से साइन किया जाता है — न कि
/v1/developer/webhook-endpoints के किसी प्रति-एंडपॉइंट सीक्रेट से। वही verify()
फ़ंक्शन दोबारा उपयोग करें, लेकिन सुनिश्चित करें कि टूल रूट्स पर आप उसे संगठन सीक्रेट दें।GET/DELETE टूल्स पर क्वेरी स्ट्रिंग को हैश करना
GET/DELETE टूल्स पर क्वेरी स्ट्रिंग को हैश करना
बिना बॉडी वाले टूल मेथड्स के लिए सिग्नेचर खाली बाइट
स्ट्रिंग को कवर करता है, जिससे एक यूनिवर्सल रेसिपी बनी रहती है: रॉ रिक्वेस्ट बॉडी का HMAC करें,
चाहे वह जो भी हो। URL या क्वेरी स्ट्रिंग को हैश करने पर कभी मिलान नहीं होगा।
मिसमैच पर 401 रिटर्न न करना
मिसमैच पर 401 रिटर्न न करना
असफल वेरिफ़िकेशन पर 200 रिटर्न करने से हैंडलर रीप्ले
टारगेट बन जाता है। वेरिफ़िकेशन विफल होने पर हमेशा non-2xx रिस्पॉन्स दें।
अगले चरण
वेबहुक ओवरव्यू
डिलीवरी सेमांटिक्स, रिट्राइज़, सोर्स IPs।
वेबहुक एंडपॉइंट्स
कई URLs मैनेज करें, सीक्रेट्स रोटेट करें।
फ़ंक्शन टूल्स
दो टूल-इनवोकेशन पाथ्स और उनके रिक्वेस्ट शेप्स।
टूल इंटीग्रेशंस
शुरू से अंत तक एक पूर्ण टूल-आधारित इंटीग्रेशन बनाएँ।