شرح Webhooks: الحمولات الموقعة واستراتيجيات إعادة المحاولة

Backend2026-10-21TryQuickToolBox

لقد قمت ببناء واجهة برمجة تطبيقات (API) ترسل webhooks إلى نقاط نهاية المستخدمين. ولكن بعد ذلك تواجه المشكلات الكلاسيكية: كيف تضمن أن الحمولة لم يتم التلاعب بها؟ ماذا يحدث عندما تكون نقطة النهاية معطلة؟ كيف تمنع المعالجة المكررة؟ في هذه المقالة، سنتعامل مع هذه التحديات مباشرة باستخدام الحمولات الموقعة واستراتيجيات إعادة المحاولة القوية.

لماذا تحتاج webhooks إلى توقيعات

webhooks هي عمليات استدعاء HTTP (callbacks) تُعلم الأنظمة الأخرى بالأحداث. نظرًا لأنها تُرسل عبر الإنترنت العام، فهي عرضة للاعتراض والانتحال. بدون توقيع، يمكن لجهة خبيثة إرسال webhooks مزيفة إلى مستخدميك، مما يؤدي إلى إجراءات غير مقصودة. توقيع الحمولات باستخدام سر مشترك يضمن الأصالة والسلامة.

كيف تعمل الحمولات الموقعة

النهج الأكثر شيوعًا هو HMAC (رمز المصادقة القائم على التجزئة) مع SHA-256. يشترك المرسل والمستقبل في مفتاح سري. يحسب المرسل توقيعًا على الحمولة (وأحيانًا طابع زمني) ويضمنه في ترويسة. يعيد المستقبل حساب التوقيع ويقارنه بالتوقيع المستلم.

خطوة بخطوة: توقيع الحمولة

  1. إنشاء الحمولة: قم بتسلسل بيانات الحدث إلى JSON. تأكد من التنسيق المتسق (مثل عدم وجود مسافات إضافية) لأن التوقيع يُحسب على البايتات الدقيقة.
  2. إضافة طابع زمني: قم بتضمين طابع زمني Unix في الحمولة أو الترويسة لمنع هجمات إعادة التشغيل. يمكن للمستقبل رفض الطلبات الأقدم من بضع دقائق.
  3. حساب HMAC: استخدم مفتاحك السري لتوليد HMAC-SHA256 لسلسلة الحمولة (أو الطابع الزمني + الحمولة).
  4. إرفاق التوقيع: أرسله في ترويسة مثل X-Signature.

إليك مثالاً في Python:

import hmac
import hashlib
import json
import time

secret = b'your_shared_secret'
payload = {"event": "user.created", "data": {"id": 123}}
body = json.dumps(payload, separators=(',', ':'))
timestamp = str(int(time.time()))
signed_content = timestamp + '.' + body
signature = hmac.new(secret, signed_content.encode(), hashlib.sha256).hexdigest()

# Send headers: X-Signature: signature, X-Timestamp: timestamp

التحقق من التوقيع

على الجانب المستقبل، يجب عليك:

مثال التحقق في Node.js:

const crypto = require('crypto');

function verifySignature(req, secret) {
  const signature = req.headers['x-signature'];
  const timestamp = req.headers['x-timestamp'];
  if (!signature || !timestamp) return false;
  if (Date.now() / 1000 - timestamp > 300) return false; // 5 min
  const body = JSON.stringify(req.body);
  const signed = timestamp + '.' + body;
  const expected = crypto.createHmac('sha256', secret).update(signed).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

تصميم استراتيجيات إعادة المحاولة

حتى مع التوقيعات، يمكن أن تفشل webhooks بسبب مشكلات الشبكة أو أخطاء الخادم أو المهلات. استراتيجية إعادة المحاولة القوية تضمن التسليم دون إغراق المستقبل.

الاعتبارات الرئيسية

تنفيذ إعادة المحاولة

يستخدم معظم مرسلي webhook نظام قائمة انتظار (مثل Redis أو RabbitMQ أو قاعدة بيانات) لجدولة إعادة المحاولة. إليك تدفقًا مبسطًا:

  1. عند تفعيل الحدث، ضع مهمة webhook في قائمة الانتظار مع الحمولة وعنوان URL الهدف.
  2. يأخذ العامل المهمة ويحاول التسليم.
  3. إذا كانت حالة الاستجابة 2xx، ضع علامة نجاح.
  4. إذا لم يكن كذلك، جدول إعادة محاولة مع exponential backoff، حتى الحد الأقصى للمحاولات.
  5. بعد الحد الأقصى للمحاولات، ضع علامة فشل وأبلغ.

مثال على جدول إعادة المحاولة:

المحاولةالتأخير
1فوري
2دقيقة واحدة
35 دقائق
430 دقيقة
5ساعتان

أفضل الممارسات لأمان webhook

الأسئلة الشائعة

ما هي حمولة webhook الموقعة؟

تتضمن الحمولة الموقعة توقيعًا تشفيريًا (عادة HMAC) يسمح للمستقبل بالتحقق من أصالة المرسل وأن الحمولة لم يتم التلاعب بها.

كم مرة يجب أن أعيد محاولة webhook فاشل؟

لا توجد إجابة واحدة تناسب الجميع، ولكن النهج الشائع هو 3-5 محاولات إعادة مع exponential backoff. ضع في اعتبارك أهمية الحدث وقدرة المستقبل.

هل يمكنني استخدام JWT لتوقيعات webhook؟

نعم، يمكن استخدام JWT، لكنه أكثر تعقيدًا. HMAC أبسط وكافٍ لمعظم حالات الاستخدام. JWT مفيد إذا كنت بحاجة إلى تضمين مطالبات أو انتهاء صلاحية داخل التوقيع نفسه.

هل أنت مستعد لاختبار حمولات webhook الخاصة بك؟ استخدم JSON Formatter للتحقق من حمولات JSON الخاصة بك وتنسيقها بشكل جميل قبل الإرسال.