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

Backend2026-11-02TryQuickToolBox

لماذا تحتاج Webhooks إلى التوقيعات وإعادة المحاولة

لقد أنشأت نقطة نهاية لتلقي webhooks من مزود خدمة الدفع أو منصة SaaS. كل شيء يعمل في الاختبار، ولكن في الإنتاج تواجه مشكلتين: كيف تعرف أن الطلب جاء بالفعل من المزود، وماذا يحدث عندما يكون خادمك معطلاً أو بطيئًا؟ بدون حمولات موقعة، يمكن لأي شخص تزوير طلب. وبدون إعادة المحاولة، يمكن أن تؤدي أي عثرة في الشبكة إلى فقدان حدث إلى الأبد.

يشرح هذا الدليل كيفية تنفيذ كليهما بشكل صحيح. سنغطي توقيع HMAC، وخطوات التحقق، واستراتيجيات إعادة المحاولة، وidempotency — الأعمدة الثلاثة للتعامل الموثوق مع webhooks.

كيف تعمل توقيعات Webhook

توقيع webhook هو تجزئة تشفيرية تثبت أن الحمولة تم إنشاؤها بواسطة شخص يعرف سرًا مشتركًا. يستخدم معظم المزودين HMAC-SHA256. يقوم المرسل بحساب التوقيع على جسم الطلب الخام (أحيانًا مع طابع زمني) ويضمّنه في رأس. يقوم المستقبل بإعادة حسابه ومقارنته.

إليك تدفقًا نموذجيًا:

  1. يشترك المزود والمستهلك في مفتاح سري (يتم تكوينه في لوحة تحكم المزود).
  2. ينشئ المزود الحمولة، ويحسب HMAC-SHA256(secret, payload)، ويرسلها في رأس مثل X-Signature.
  3. يستقبل المستهلك الطلب، ويقرأ الجسم الخام، ويعيد حساب HMAC، ويقارن باستخدام دالة ثابتة الوقت.
  4. إذا تطابقت، يعالج الحدث؛ وإلا يرفض بـ 401.

هام: استخدم دائمًا جسم الطلب الخام كما تم استلامه، وليس نسخة محللة ومعاد تسلسلها. يمكن أن يغير تسلسل JSON المسافات وترتيب المفاتيح، مما يكسر التوقيع.

إضافة الطوابع الزمنية لمنع هجمات إعادة التشغيل

يمكن للمهاجم الذي يلتقط طلبًا صالحًا إعادة تشغيل الحمولة الموقعة وحدها. للتخفيف من ذلك، قم بتضمين طابع زمني في البيانات الموقعة وارفض الطلبات الأقدم من بضع دقائق. على سبيل المثال:

signed_payload = timestamp + "." + raw_body
signature = HMAC-SHA256(secret, signed_payload)

يتحقق المستهلك من أن الطابع الزمني ضمن نافذة مقبولة (مثل 5 دقائق) وأن التوقيع يتطابق.

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

لنلقِ نظرة على مثال ملموس في Python باستخدام Flask. سنتحقق من توقيع مرسل في رأس X-Signature.

import hmac
import hashlib
from flask import Flask, request, abort

app = Flask(__name__)
SECRET = b'your_shared_secret'

@app.route('/webhook', methods=['POST'])
def webhook():
    signature = request.headers.get('X-Signature')
    if not signature:
        abort(401)

    raw_body = request.get_data()
    expected = hmac.new(SECRET, raw_body, hashlib.sha256).hexdigest()

    if not hmac.compare_digest(expected, signature):
        abort(401)

    # Process the event
    event = request.json
    # ... handle event ...
    return '', 200

النقاط الرئيسية:

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

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

إليك ما يجب مراعاته:

يعيد معظم المزودين المحاولة عند الردود غير 2xx أو المهلات، غالبًا لمدة تصل إلى 24 ساعة بفواصل زمنية متزايدة. راجع وثائق المزود للحصول على التفاصيل.

مثال: معالج أحداث Idempotent

استخدم جدول قاعدة بيانات لتتبع معرفات الأحداث المعالجة. إليك نمطًا مبسطًا:

def handle_event(event_id, payload):
    if db.exists('processed_events', event_id):
        return  # already handled
    # process payload
    db.insert('processed_events', event_id)
    # ... actual work ...

للحصول على إنتاجية عالية، استخدم قيدًا فريدًا على معرف الحدث والتقط أخطاء المفاتيح المكررة.

مقارنة: Webhooks الموقعة مقابل غير الموقعة

الجانبالحمولات الموقعةالحمولات غير الموقعة
الأمانيتحقق من أصالة المرسليمكن لأي شخص تزوير الطلبات
الحماية من إعادة التشغيلممكنة مع الطوابع الزمنيةلا شيء
جهد التنفيذمتوسط (HMAC + فحص الطابع الزمني)منخفض
موصى به لـجميع webhooks الإنتاجالاختبار الداخلي فقط

الأخطاء الشائعة وأفضل الممارسات

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

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

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

كيف أتعامل مع إعادة محاولة webhook دون تكرار الإجراءات؟

اجعل معالجك idempotent من خلال تتبع معرفات الأحداث. قبل المعالجة، تحقق مما إذا كان المعرف قد تمت معالجته بالفعل؛ إذا كان كذلك، فأعد النجاح دون تكرار العمل.

هل يمكنني استخدام webhooks بدون توقيعات؟

لا يُنصح بذلك للإنتاج. بدون توقيعات، لا يمكنك التمييز بين الطلبات المشروعة والمزورة. تحقق دائمًا من التوقيعات عند توفرها.

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