شرح Webhooks: الحمولات الموقعة وإعادة المحاولات
لماذا تعتبر Webhooks قوية وهشة في آن واحد
تشغل Webhooks عمليات التكامل في الوقت الفعلي: إشعارات الدفع، مشغلات CI/CD، رسائل الدردشة. لكنها تأتي مع تحدين كبيرين: الأمان (كيف تعرف أن الطلب من المرسل المتوقع؟) والموثوقية (ماذا لو كان المستقبل معطلاً؟). يوضح لك هذا المقال كيفية معالجة كليهما باستخدام الحمولات الموقعة واستراتيجيات إعادة المحاولة.
ما هو Webhook؟
Webhook هو طلب HTTP POST يرسله المزود إلى المستهلك عند حدوث حدث. على عكس الاستقصاء (polling)، تدفع Webhooks البيانات في الوقت الفعلي تقريباً، مما يقلل من زمن الاستجابة وحمل الخادم. يجب على المزود التأكد من أن الطلب أصلي؛ ويجب على المستهلك معالجته بشكل موثوق.
تأمين Webhooks باستخدام الحمولات الموقعة
تستخدم الحمولة الموقعة مفتاحاً سرياً لإنشاء توقيع تشفيري (عادةً HMAC-SHA256) لجسم الطلب. يعيد المستقبل حساب التوقيع ويقارنه بالتوقيع الموجود في الترويسة. إذا تطابقا، فإن الحمولة أصلية ولم يتم التلاعب بها.
كيفية إنشاء التوقيعات والتحقق منها
إليك تدفقاً نموذجياً:
- يتشارك المزود والمستهلك مفتاحاً سرياً (مثلاً عبر لوحة التحكم).
- يحسب المزود
HMAC-SHA256(secret, payload)ويرسله في ترويسة مثلX-Signature. - يقرأ المستهلك الجسم الخام، ويحسب نفس HMAC، ويقارن باستخدام دالة ثابتة الزمن.
مثال في Node.js:
const crypto = require('crypto');
function verifySignature(secret, payload, signature) {
const hmac = crypto.createHmac('sha256', secret);
hmac.update(payload);
const digest = hmac.digest('hex');
return crypto.timingSafeEqual(Buffer.from(digest), Buffer.from(signature));
}
استخدم دائماً المقارنة ثابتة الزمن لمنع هجمات التوقيت. لا تحلل الجسم قبل التحقق أبداً—استخدم برمجية وسيطة للجسم الخام.
تنفيذ إعادة المحاولات لتسليم موثوق
حتى مع التوقيعات، يمكن أن تؤدي أعطال الشبكة أو الانقطاعات المؤقتة إلى فشل تسليم Webhook. تضمن آلية إعادة المحاولة القوية التسليم النهائي.
استراتيجيات إعادة المحاولة
- التراجع الأسي: انتظر فترة أطول بين كل محاولة (مثلاً 1ث، 2ث، 4ث، 8ث).
- الحد الأقصى للمحاولات: حدد عدد المحاولات (مثلاً 5 محاولات) لتجنب الحلقات اللانهائية.
- قائمة الرسائل الميتة: بعد الحد الأقصى للمحاولات، خزّن الحدث للفحص اليدوي.
- Idempotency: أدرج معرف حدث فريداً حتى يتمكن المستهلك من تجاهل التكرارات.
مثال على منطق إعادة المحاولة في Python:
import time
import requests
def send_webhook(url, payload, max_retries=5):
for attempt in range(max_retries):
try:
response = requests.post(url, json=payload, timeout=5)
if response.status_code == 200:
return True
except requests.RequestException:
pass
time.sleep(2 ** attempt) # exponential backoff
return False
أفضل الممارسات لمستهلكي Webhook
- استجب بـ 2xx بسرعة؛ عالج بشكل غير متزامن إذا لزم الأمر.
- تحقق من التوقيع قبل أي معالجة.
- استخدم مفاتيح idempotency للتعامل مع التسليمات المكررة.
- سجّل جميع Webhooks الواردة لتصحيح الأخطاء.
- راقب حالات الفشل ونبّه عند تكرار الأخطاء.
المقارنة: الاستقصاء مقابل Webhooks
| الجانب | الاستقصاء | Webhooks |
|---|---|---|
| زمن الاستجابة | مرتفع (بناءً على الفاصل الزمني) | منخفض (في الوقت الفعلي) |
| حمل الخادم | طلبات مستمرة | فقط عند الأحداث |
| التعقيد | بسيط | يتطلب إعادة محاولة/أمان |
| حالة الاستخدام | نطاق صغير، تحديثات غير متكررة | تكاملات في الوقت الفعلي |
الأسئلة الشائعة
ما هي حمولة webhook الموقعة؟
تتضمن الحمولة الموقعة توقيعاً تشفيرياً (مثل HMAC) يسمح للمستقبل بالتحقق من أن الطلب جاء من مصدر موثوق ولم يتم التلاعب به.
كم مرة يجب أن أعيد محاولة webhook فاشل؟
لا يوجد رقم عالمي، لكن 3-5 محاولات مع التراجع الأسي شائعة. بعد ذلك، سجّل الحدث للمراجعة اليدوية.
هل يمكنني استخدام JWT بدلاً من HMAC لتوقيعات webhook؟
نعم، يستخدم بعض المزودين JWT. المبدأ هو نفسه: تحقق من توقيع الرمز ومطالباته قبل الوثوق بالحمولة.
هل تحتاج إلى فحص حمولات أو سجلات webhook؟ جرّب JSON Formatter الخاص بنا لتنسيق والتحقق من حمولات JSON بسرعة.