Octane
الويب هوك

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

تحقق من X-Octane-Signature بحساب HMAC-SHA256 على الطابع الزمني ونقطة والجسم الخام بسر الويب هوك الخاص بك. أمثلة بلغات Node.js وPython وPHP وC# وJava.

للتحقق من ويب هوك، احسب HMAC-SHA256 على <t>.<raw body> بسر الويب هوك الخاص بك وقارنه، بمقارنة ثابتة الزمن، بقيمة v1 في ترويسة X-Octane-Signature. ارفض أي طلب يفشل، وارفض الطوابع الزمنية الأقدم من بضع دقائق. تحقق دائمًا قبل التصرف بناءً على الحمولة.

الترويسة

X-Octane-Signature: t=1758358803,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
العنصرالوصف
tطابع Unix الزمني (بالثواني) الذي وقّعت فيه أوكتين الطلب.
v1HMAC-SHA256 بسداسي عشري بأحرف صغيرة للنص <t>.<raw body> بسر الويب هوك الخاص بك.

خطوات التحقق

اقرأ الجسم الخام

استخدم البايتات التي أرسلتها أوكتين بالضبط. لا تعد تسلسل JSON بعد تحليله: أي تغيير في المسافات أو ترتيب المفاتيح يغيّر التوقيع.

حلّل الترويسة

قسّم على , ثم كل جزء على = للحصول على t وv1.

تحقق من الطابع الزمني

ارفض الطلب إذا كان t بعيدًا جدًا عن وقتك الحالي. يُنصح بتسامح 5 دقائق. هذا يحد من إعادة إرسال الطلبات الملتقطة.

احسب التوقيع المتوقع

signed_payload = t + "." + raw_body، ثم HMAC_SHA256(secret, signed_payload) بسداسي عشري بأحرف صغيرة.

قارن بزمن ثابت

قارن قيمتك مع v1 بدالة مقارنة ثابتة الزمن. المقارنة النصية العادية تسرّب معلومات توقيت.

أمثلة الكود

يعرض كل مثال دالة verify(rawBody, signatureHeader, secret) ويوضح كيفية قراءة الجسم الخام في إطار عمل شائع.

const crypto = require('node:crypto');

const TOLERANCE_SECONDS = 300;

function verifyOctaneSignature(rawBody, header, secret) {
  if (typeof header !== 'string') return false;

  const parts = Object.fromEntries(
    header.split(',').map((kv) => kv.split('=').map((s) => s.trim())),
  );
  const t = Number(parts.t);
  const v1 = parts.v1;
  if (!Number.isFinite(t) || !v1) return false;

  if (Math.abs(Date.now() / 1000 - t) > TOLERANCE_SECONDS) return false;

  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${t}.${rawBody}`)
    .digest('hex');

  const a = Buffer.from(expected, 'hex');
  const b = Buffer.from(v1, 'hex');
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

// Express: keep the raw body for this route
const express = require('express');
const app = express();

app.post(
  '/webhooks/octane',
  express.raw({ type: 'application/json' }),
  (req, res) => {
    const rawBody = req.body.toString('utf8');
    const ok = verifyOctaneSignature(
      rawBody,
      req.get('X-Octane-Signature'),
      process.env.OCTANE_WEBHOOK_SECRET,
    );
    if (!ok) return res.status(401).send('invalid signature');

    const event = JSON.parse(rawBody);
    // Acknowledge first, process asynchronously
    res.sendStatus(200);
    queue.enqueue(event);
  },
);

أخطاء شائعة

  • تحليل الجسم قبل التجزئة. أطر العمل التي تحلل JSON تلقائيًا غالبًا تتخلص من البايتات الخام. اضبط المسار للاحتفاظ بها كما هو موضح أعلاه.
  • تجزئة الجسم وحده. الحمولة الموقّعة هي t + "." + body، لا الجسم وحده.
  • المقارنة بـ ==. استخدم المقارنة ثابتة الزمن التي توفرها منصتك.
  • انحراف الساعة. إذا فشلت الطلبات الصحيحة في فحص الطابع الزمني، زامن ساعة خادمك عبر NTP قبل توسيع التسامح.
  • سداسي عشري بأحرف كبيرة. ترسل أوكتين أحرفًا صغيرة. قارن البايتات، أو وحّد حالة الأحرف قبل مقارنة النصوص.

كيف أختبر محليًا؟

اطلب من أوكتين إرسال حدث webhook.test، أو ولّد واحدًا بنفسك بسرك:

SECRET="your_webhook_secret"
BODY='{"id":"test","type":"webhook.test","created_at":"2026-09-20T09:00:03Z","api_version":"2026-09-01","data":{}}'
T=$(date +%s)
SIG=$(printf '%s.%s' "$T" "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | sed 's/^.* //')

curl -X POST https://localhost:8443/webhooks/octane \
  -H "Content-Type: application/json" \
  -H "X-Octane-Event: webhook.test" \
  -H "X-Octane-Delivery: test" \
  -H "X-Octane-Signature: t=$T,v1=$SIG" \
  --data-binary "$BODY"

أسئلة شائعة

كيف أتحقق من توقيع ويب هوك أوكتين؟
اقرأ جسم الطلب الخام، وخذ t وv1 من ترويسة X-Octane-Signature، واحسب HMAC-SHA256 للنص "<t>.<raw body>" بسر الويب هوك كسداسي عشري بأحرف صغيرة، وقارنه بـ v1 بمقارنة ثابتة الزمن. ارفض الطوابع الزمنية الأقدم من نحو 5 دقائق.
لماذا يفشل التحقق من التوقيع لدي؟
الأسباب الأشيع: تجزئة جسم JSON بعد إعادة تسلسله بدل البايتات الخام، أو نسيان البادئة "<t>."، أو مقارنة سداسي عشري بأحرف كبيرة، أو ساعة خادم غير متزامنة. أصلح التعامل مع الجسم الخام أولًا.
من أين أحصل على سر الويب هوك؟
تولّده أوكتين عند ضبط عنوان الويب هوك وتشاركه معك مرة واحدة مع مفتاح API. لا يُعرض مجددًا ولا يُدوَّر أبدًا. إذا فقدته، تصدر أوكتين مفتاحًا جديدًا بسر جديد.

في هذه الصفحة