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 — راجع وثائقهما حول “النص الخام”.مقارنة غير آمنة زمنيًا
مقارنة غير آمنة زمنيًا
تمثل
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 متعددة، ودوّر الأسرار.
أدوات الدوال
مسارا استدعاء الأدوات وأشكال طلباتهما.
تكاملات الأدوات
أنشئ تكاملًا كاملًا مدعومًا بأداة من البداية إلى النهاية.