دليل · واجهة API للبريد الإلكتروني
كيف ينفّذ فريق المنتج واجهة API للبريد الإلكتروني بأمان؟
نفّذ واجهة API للبريد الإلكتروني بوصفها سير عمل غير متزامنًا وخاضعًا للصلاحيات، لا استدعاءً مباشرًا من النموذج إلى المزوّد. صادِق على المستدعي، وتأكد من أن المستأجر يملك نطاق From موثَّقًا، وتحقق من الرسالة وحجمها، وعيّن معرّف مهمة ثابتًا للتطبيق، وضعها في الطابور مرة واحدة، ثم أرسلها من عامل (worker). سجّل معرّف رسالة المزوّد عند القبول، واستقبل أحداث التسليم بطريقة غير مكرّرة، وامنع الارتدادات الدائمة والشكاوى. لا تستخدم إعادة المحاولة المحدودة إلا حين يكون خطر التكرار مضبوطًا. أبقِ بيانات الاعتماد على الخادم، وقلّل بيانات الرسائل في السجلات، وميّز بين قبول API وتسليم خادم البريد والوصول إلى صندوق الوارد.
حدّد حدود API قبل اختيار المزوّد
ينبغي أن تكشف واجهة API للبريد الإلكتروني نيّة التطبيق دون تسريب كل تفاصيل المزوّد إلى شيفرة المنتج. عرّف موارد للرسائل ونطاقات الإرسال ومفاتيح API والأحداث وقوائم المنع. وحدّد الحقول التي يجوز للمستدعين التحكم فيها، ومنها From وTo وReply-To والموضوع والنص وHTML وقائمة سماح صغيرة من الترويسات. ارفض ترويسات النقل التي يزوّدها المستدعي إذا كانت قد تتعارض مع توقيع المزوّد أو توجيهه. تعامل مع الإرسال بوصفه عملية كتابة ذات عواقب: ينبغي أن تحدد الاستجابة مورد رسالة في التطبيق وحالته الحالية، لا أن توحي بنتيجة في صندوق البريد. أبقِ حساب المزوّد والمنطقة (Region) ومجموعة الإعدادات ومعرّفات النقل خلف محوّل (adapter). يتيح هذا الحد ترحيل المزوّد، ويمنح ضوابط التفويض والاحتفاظ وإساءة الاستخدام مكانًا ثابتًا.
صادِق على المستدعين وفوّض كل نطاق إرسال
خزّن مفاتيح API على هيئة تجزئات أحادية الاتجاه فقط، واعرض السر كاملًا مرة واحدة. امنح كل مفتاح مالكًا من مساحة العمل وحالة ووقت إنشاء ومسار إبطال؛ وأضف صلاحيات أضيق عندما ينبغي لتكامل ما أن يرسل فقط أو أن يقرأ الأحداث فقط. تجيب المصادقة عن سؤال من قدّم بيانات الاعتماد، بينما يقرر التفويض ما إذا كان يجوز لذلك الطرف استخدام نطاق From المطلوب ومورد الرسالة. تحقق من ملكية النطاق عند كل إرسال، بما في ذلك نقاط نهاية الدفعات، بدلًا من الوثوق بمعرّف نطاق يوفّره العميل. اشترط توثيق المزوّد قبل تفعيل حركة الإنتاج. ولا تضع أبدًا بيانات اعتماد المزوّد أو مفاتيح API الخاصة بمساحة العمل في JavaScript المتصفح أو سلاسل الاستعلام أو التحليلات أو رسائل الخطأ. ويكتسب التفويض على مستوى الكائن أهمية خاصة لمعرّفات الرسائل والأحداث والمنع وصناديق الوارد والنطاقات في واجهة API متعددة المستأجرين.
وثّق النطاق وحاذِ المصادقة
يحتاج نطاق الإرسال إلى أكثر من علامة في قاعدة البيانات. أكمل فحص الملكية لدى المزوّد وانشر سجلات DKIM المطلوبة. تفوّض SPF المضيفين لهوية SMTP MAIL FROM أو HELO، بينما تربط DKIM نطاق التوقيع بتوقيع تشفيري للرسالة. وتقيّم DMARC ما إذا كان معرّف SPF أو DKIM الناجح محاذيًا لنطاق From الظاهر في RFC 5322، وتتيح لمالك النطاق نشر سياسة معالجة وإبلاغ. وإذا كان للنطاق SPF بالفعل، فادمج الآلية المطلوبة في السجل الحالي؛ إذ ينص RFC 7208 على أنه يجب ألا ينشر النطاق سجلات متعددة تؤدي إلى اختيار أكثر من سجل SPF واحد. ولا تطبّق سياسة DMARC أشد إلا بعد أن تُظهر رسائل مضبوطة وتقارير مجمّعة أن كل مُرسِل مشروع محاذٍ. تقلل المصادقة الاستخدام غير المصرح به للنطاق، لكنها لا تضمن الوصول إلى صندوق الوارد.
تحقق من بنية الرسالة وقلّل المدخلات المقبولة
يعرّف RFC 5322 رسالة الإنترنت بأنها حقول ترويسة يتبعها متن اختياري، وتوسّع مواصفات MIME المحتوى إلى ما يتجاوز النص الأساسي. تستطيع واجهة API إخفاء معظم تفاصيل تنسيق النقل مع الاستمرار في فرضها. وحّد مصفوفات المستلِمين، وحدّد عدد المستلِمين والحجم المشفَّر الإجمالي، واشترط متنًا نصيًا أو HTML واحدًا على الأقل، وتحقق من العناوين دون التظاهر بأن الصياغة تثبت وجود صندوق البريد. أزل محارف الإرجاع (CR) وتغذية السطر (LF) من الحقول التي تتحول إلى ترويسات. أنشئ Message-ID أو دع المزوّد ينشئه؛ ولا تعِد استخدامه معرّفًا لمهمة التطبيق لأن نسخة جديدة من الرسالة قد تستحق معرّفًا جديدًا بحق. اسمح فقط بالترويسات المخصصة الموثَّقة، وارفض تكرار الحقول المحمية، واعرض القوالب قبل التسليم إلى المزوّد حتى تخفق المتغيرات المفقودة في حالة مضبوطة داخل التطبيق.
ضع في الطابور مرة واحدة واستخدم معرّفات تطبيق ثابتة
ينبغي أن ينشئ طلب المستخدم مهمة رسالة دائمة واحدة داخل معاملة، ثم ينفّذ عامل استدعاء المزوّد. امنح المهمة معرّفًا ثابتًا وسجّل بصمة للطلب أو مفتاح عدم تكرار (idempotency key) يوفّره المستدعي عندما يدعمه العقد. يعرّف HTTP الطلب POST بأنه غير idempotent افتراضيًا، ويحذّر من إعادة المحاولة التلقائية ما لم يعلم العميل أن العملية بحكم الـ idempotent أو أن الطلب الأصلي لم يُطبَّق. وهذا مهم في البريد لأن انتهاء المهلة قد يقع بعد أن قبل المزوّد الرسالة وقبل أن يتلقى العامل الاستجابة. وعند الإخفاق الملتبس، قارن أولًا حالة المهمة المخزّنة بحالة المزوّد بدلًا من إنشاء إرسال جديد. استخدم نمط outbox عندما ينبغي أن تتحرك حالة التطبيق ونشر الطابور معًا، وضع قيد تفرّد حول حد عدم التكرار.
صمّم إعادة المحاولات وفق فئات الإخفاق
افصل بين التحقق من الصحة والتفويض والتقييد (throttling) ورفض المزوّد وإخفاق النقل المؤقت وإخفاق التسليم إلى المستلِم. ينبغي أن يخفق المدخل غير الصالح ونطاق From غير المفوَّض دون إعادة محاولة. أما حدود معدل المزوّد وأخطاء الخدمة المؤقتة فيمكن إعادة محاولتها بتراجع أُسّي محدود مع تشويش عشوائي (jitter) وسقف لعدد المحاولات ومهلة ظهور في الطابور أطول من مهلة طلب العامل. والانتهاء الملتبس لمهلة الشبكة يحتاج إلى مطابقة تراعي التكرار بدلًا من طلب جديد غير مشروط. يميّز SMTP نفسه بين ردود 4xx المؤقتة وردود 5xx الدائمة، لكن التطبيق الذي يستخدم API مزوّد ينبغي أن يتبع دلالات الأخطاء الموثَّقة لدى ذلك المزوّد. انقل المهام المستنفدة إلى حالة dead-letter قابلة للمراجعة واحتفظ بالسبب بعد تنقيته. ولا تعِد محاولة ارتداد دائم للمستلِم كما لو كان انقطاعًا في API، ولا تحوّل الشكوى إلى محاولة إرسال أخرى.
سجّل القبول واستقبل أحداث التسليم
ثبّت معرّف رسالة المزوّد فورًا بعد القبول واربطه بمعرّف رسالة التطبيق. عندئذ يمكن لأحداث المزوّد تحديث المورد الصحيح حتى إذا حجبت شكوى تفاصيل المستلِم. تميّز Amazon SES، على سبيل المثال، بين إرسال ناجح وتسليم إلى خادم بريد المستلِم، ويمكنها نشر أحداث التسليم والارتداد والشكوى والرفض وتأخير التسليم وفشل العرض والفتح والنقر. تحقق من أصالة webhook باستخدام آلية المزوّد الموثقة، وتحقق من مخطط الحدث، وأزل التكرار باستخدام معرّف حدث المزوّد أو بصمة حتمية، واسمح بتسليم الحدث نفسه مرارًا من دون تكرار الآثار الجانبية. خزّن الحمولات الخام فقط عند الضرورة، مشفرةً ومضبوطة الوصول ومحدودة الاحتفاظ. يجب أن تميّز الحالة المعيارية بين نتائج المقبول والمسلم إلى الخادم والمرتد والمشتكى منه والمتأخر والمرفوض والممنوع.
اجعل المنع ضابطًا وقت الإرسال
ينبغي فحص سجل المنع قبل كل تسليم إلى المزوّد، لا عرضه في لوحة التحكم فقط. تتطلب العناوين المرتدة دائمًا والشكاوى عادةً المنع؛ أما تأخيرات التسليم المؤقتة فتحتاج إلى سياسة مختلفة. حدّد نطاق المنع عن قصد. فقائمة على مستوى الحساب قد تحمي السمعة المشتركة لكنها قد تجعل نتيجة مستلِم لدى مستأجر تحجب مستأجرًا آخر. وقائمة على مستوى المستأجر تقلل هذا الاقتران لكنها تظل بحاجة إلى طبقة لإساءة الاستخدام وسلامة المنصة. سجّل السبب وحدث المصدر والمستأجر ووقت الإنشاء ومسار إزالة مضبوطًا. وإزالة منع ناتج عن شكوى أو ارتداد دائم إجراء ذو عواقب، وينبغي أن تتطلب مراجعة متعمدة ودليلًا على أن العنوان صالح وأن المستلِم يتوقع الرسالة. تجنّب نسخ عناوين المستلِمين الخام إلى السجلات العامة أو التجارب؛ إذ يستطيع التخزين التشغيلي فرض سياسة الإرسال بينما تستخدم التحليلات أعدادًا مجمّعة.
احمِ الإرسال بالدفعات وتدفقات الأعمال الحساسة
تضاعف نقطة نهاية الدفعات أثر أي خطأ في التفويض أو التحقق. طبّق فحوص ملكية النطاق والمنع والحجم والمحتوى نفسها على كل عنصر، وفرض حدًا أقصى صارمًا لطول الدفعة، وأعد نتائج لكل عنصر دون تسريب بيانات مستأجر آخر. ينبغي أن توجد حدود المعدّل على مستوى بيانات الاعتماد ومساحة العمل والنطاق والمزوّد، مع ضوابط منفصلة للطفرات وللحجم المتحرك. ولا يكفي حد عام واحد للطلبات في الثانية لأن الطلب الواحد قد يحتوي على مستلِمين كثيرين. اشترط تأكيدًا متعمدًا في الأدوات التي يقودها الوكلاء قبل إرسال دفعة عالية الأثر. وافصل صلاحيات البريد المعاملاتي والتسويقي عندما تختلف قواعد الموافقة والتشغيل فيهما. راقب نمو المستلِمين غير المعتاد، والنطاقات المرفوضة المتكررة، وتغيّرات الارتداد أو الشكاوى المرتفعة، والإنشاء السريع للمفاتيح. يدعم حد المعدّل السلامة، لكنه لا يحل محل المصادقة والتفويض على مستوى الكائن وموافقة موثَّقة والاستجابة لإساءة الاستخدام.
اختبر مسارات الإخفاق قبل الإنتاج
استخدم محاكيات المزوّد أو صناديق بريد مضبوطة لاختبار القبول والتسليم إلى الخادم المستقبِل والارتداد الدائم والشكوى والتأخير والنطاق غير الصالح والمفتاح المبطَل والتقييد ومهلة المزوّد وwebhook المكرّر وإعادة تسليم الطابور. تأكد من أن مفتاح عدم التكرار نفسه ينشئ رسالة تطبيق واحدة، وأن إعادة تشغيل حدث لا تنتج أثرًا جانبيًا مكرّرًا، وأن أي مستأجر لا يستطيع القراءة أو الإرسال بنطاق مستأجر آخر أو بمعرّف رسالته. افحص رسالة حقيقية مستلَمة من حيث From وReturn-Path وDKIM وSPF ومحاذاة DMARC وعرض النص وHTML وسلوك إلغاء الاشتراك حيثما ينطبق والروابط. اختبر حمل الطابور دون حدود المزوّد المعتمدة وتحقق من الضغط العكسي (backpressure) بدلًا من تجاوزه. وأضف تنبيهات لعمر الطابور وإعادة المحاولات المستنفدة وإخفاقات استقبال الأحداث وهامش الحصة وتغيّرات الارتداد والشكاوى واستدعاءات المزوّد المفقودة. وينبغي أن تسمّي قائمة التحقق قبل الإطلاق مالكًا لكل تنبيه وإجراء استرداد.
طبّق النمط مع SendHQ بحذر
يوفر SendHQ مفاتيح bearer على مستوى مساحة العمل، وفحوصات نطاق From الموثَّق، وإنشاء الرسائل الفردية والمجمعة، وصناديق بريد وارد، وأحداث الرسائل، وموارد المنع. تدعم هذه الميزات البنية في هذا الدليل: أبقِ المفتاح على الخادم، وأنشئ مورد رسالة، واحتفظ بمعرّفه، واقرأ الأحداث اللاحقة بدلًا من التعامل مع الاستجابة الأولية بوصفها التسليم النهائي. وبصرف النظر عن المنصة، يظل المتصلون مسؤولين عن المستلِمين المقصودين والبريد القانوني والمتوقع ودقة المحتوى والموافقة المتأنية على عمليات الإرسال ذات العواقب.
الأسئلة الشائعة
هل ينبغي أن ترسل واجهة API للبريد الإلكتروني بشكل متزامن من طلب الويب؟
عادةً لا. أنشئ رسالة تطبيق دائمة وضعها في الطابور، ثم دع عاملًا يستدعي المزوّد. يعزل هذا زمن الاستجابة، ويدعم إعادة المحاولات المحدودة، ويسهّل مطابقة نتائج المزوّد الملتبسة.
كيف أمنع تكرار الرسائل عند انتهاء مهلة الطلب؟
استخدم معرّف مهمة ثابتًا للتطبيق وحدًّا لعدم التكرار مع قيد تفرّد. وعند انتهاء مهلة ملتبس، طابِق المهمة الموجودة قبل إصدار تسليم آخر إلى المزوّد بهوية جديدة.
هل تعني استجابة ناجحة من API للبريد الإلكتروني أن الرسالة سُلِّمت؟
لا. فهي تدل عادةً على أن API أو المزوّد قبل الطلب. استخدم الأحداث اللاحقة للتمييز بين التسليم إلى الخادم المستقبِل والارتداد والشكوى والتأخير والرفض والمنع وبين القبول الأولي.
ما سجلات DNS التي تحتاجها واجهة API للبريد الإلكتروني؟
تعتمد السجلات الدقيقة على المزوّد، لكن الإرسال في بيئة الإنتاج يتطلب عادةً توثيق النطاق وDKIM، إضافة إلى استراتيجية SPF صحيحة وسياسة DMARC محاذية لتدفقات الإرسال المشروعة.
هل ينبغي تخزين مفاتيح API في شيفرة المتصفح؟
لا. أبقِ بيانات اعتماد مساحة العمل والمزوّد في تخزين أسرار على الخادم، وجزّئ مفاتيح API الخاصة بالتطبيق أثناء التخزين حيثما أمكن، واعرض الأسرار كاملة مرة واحدة، ووفّر مسارات سريعة للإبطال والتدوير.
كيف ينبغي أن تتعامل واجهة API للبريد الإلكتروني مع الارتدادات الدائمة؟
وحّد حدث المزوّد، واربطه برسالة التطبيق، وامنع الإرسال الروتيني المستقبلي إلى ذلك المستلِم ضمن النطاق المقصود. ينبغي أن تكون الإزالة متعمدة ومدعومة بأدلة.
المصادر
- RFC 9110: HTTP Semantics — مرجع IETF
- RFC 5321: Simple Mail Transfer Protocol — مرجع IETF
- RFC 5322: Internet Message Format — مرجع IETF
- RFC 6376: DomainKeys Identified Mail Signatures — مرجع IETF
- RFC 7208: Sender Policy Framework — مرجع IETF
- RFC 7489: Domain-based Message Authentication, Reporting, and Conformance — مرجع IETF
- مراقبة نشاط الإرسال في Amazon SES — Amazon Web Services
- استكشاف أخطاء إشعارات Amazon SES — Amazon Web Services
- OWASP API Security Top 10 2023 — مؤسسة OWASP
- عقد SendHQ OpenAPI — SendHQ