فشل رد الاتصال OAuth2 لـ Microsoft Outlook مع خطأ 502 Bad Gateway على n8n المستضافة ذاتيًا

فشل رد الاتصال OAuth2 لـ Microsoft Outlook مع خطأ 502 Bad Gateway على n8n المستضاف ذاتيًا

وصف المشكلة/الخطأ/السؤال

أحاول توصيل حساب Microsoft Outlook بمثيل n8n مستضاف ذاتيًا باستخدام بيانات اعتماد Microsoft Outlook OAuth2 المدمجة وتسجيل تطبيق Microsoft Entra ID.

مصادقة Microsoft نفسها تعمل:

  1. أنقر على Connect my account في بيانات اعتماد Microsoft Outlook.

  2. يعيد توجيه n8n إلى Microsoft.

  3. يمكنني تحديد والمصادقة باستخدام حساب Microsoft 365 الخاص بي.

  4. تعيد Microsoft توجيه المتصفح بنجاح إلى:

https://n8n.example.com/rest/oauth2-credential/callback?code=<REDACTED>&state=<REDACTED>

  1. يفشل رد الاتصال بعد ذلك ويتلقى المتصفح:
502 Bad Gateway
Server: nginx

مثيل n8n موجود خلف خادم وكيل عكسي Nginx.

استكشاف الأخطاء الذي تم إجراؤه بالفعل

1. التحقق من الاتصال بين Nginx و n8n

من خادم الوكيل العكسي:

curl -v http://<N8N_INTERNAL_IP>:5678/healthz

النتيجة:

HTTP/1.1 200 OK
{"status":"ok"}

لذا يمكن للوكيل العكسي التواصل بنجاح مع n8n.

طلبات واجهة المستخدم/API العادية من n8n تعمل أيضًا.


2. التحقق من وصول رد الاتصال OAuth إلى خادم n8n

استخدمنا tcpdump بين الوكيل العكسي وخادم n8n.

رد الاتصال من Microsoft يصل بالتأكيد إلى n8n:

GET /rest/oauth2-credential/callback?code=<REDACTED>&state=<REDACTED> HTTP/1.1
Host: n8n.example.com
X-Real-IP: <REDACTED>
X-Forwarded-For: <REDACTED>
X-Forwarded-Proto: https

ومع ذلك، أثناء فشل رد اتصال OAuth، لاحظنا إعادة تعيين الاتصال حول معالجة رد الاتصال.

الطلبات العادية مثل /healthz تعيد 200 OK.


3. اختبار رؤوس وكيل Nginx

لاحظنا أن الطلبات الأصلية كانت تحتوي على:

Connection: upgrade

اختبرنا الوكيل باستخدام:

Connection: close

للطلبات العادية HTTP.

طلبات n8n العادية استمرت في العمل، لكن رد الاتصال OAuth لا يزال يفشل.


4. التحقق من Entra redirect URI

معرف إعادة التوجيه المكوّن في تسجيل تطبيق Entra هو:

https://n8n.example.com/rest/oauth2-credential/callback

فحصنا عنوان URL للتفويض الذي تم إنشاؤه بواسطة n8n.

يحتوي على:

client_id=<REDACTED_CLIENT_ID>
redirect_uri=https%3A%2F%2Fn8n.example.com%2Frest%2Foauth2-credential%2Fcallback
response_type=code
response_mode=query
prompt=select_account

لذلك فإن معرّف العميل ومعرف إعادة التوجيه الذي تم إنشاؤه بواسطة n8n يطابق تكوين Entra.


5. إعادة إنشاء تسجيل تطبيق Entra

للقضاء على مشكلة محتملة مع تسجيل التطبيق الأصلي، أنشأنا تطبيق Entra جديد مخصص لـ n8n.

تمت إضافة أذونات Microsoft Graph المفوضة المطلوبة من قبل بيانات اعتماد Outlook وتم منح موافقة المسؤول.

بقيت المشكلة بالضبط كما هي.

اختبرنا أيضًا نقاط نهاية خاصة بالمستأجر بدلاً من /common:

https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/authorize

https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token

بقيت المشكلة.


6. التحقق من معرف العميل والسر العميل مباشرة من داخل حاوية n8n

هذا هو الجزء الذي يجعل المشكلة محيّرة بشكل خاص.

من داخل حاوية n8n نفسها، قمنا باستدعاء نقطة نهاية رمز Microsoft يدويًا باستخدام معرف العميل والسر العميل من نفس تطبيق Entra.

على سبيل المثال:

POST https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token

client_id=<REDACTED>
client_secret=<REDACTED>
grant_type=client_credentials
scope=https://graph.microsoft.com/.default

أعادت Microsoft بنجاح:

{
  "token_type": "Bearer",
  "expires_in": 3599,
  "access_token": "<REDACTED>"
}

هذا يؤكد ما يلي:

  • حل أسماء DNS يعمل من حاوية n8n

  • HTTPS الصادر من الحاوية إلى Microsoft يعمل

  • نقطة نهاية رمز Microsoft/المستأجر قابلة للوصول

  • معرف العميل صالح

  • السر العميل صالح

أنا أفهم أن client_credentials و authorization_code عبارة عن تدفقات OAuth مختلفة، لكن هذا الاختبار على الأقل يؤكد أن Microsoft تقبل معرف العميل/السر لهذا التطبيق من حاوية n8n.


7. فحص تطبيق بيانات اعتماد Microsoft OAuth2 المثبت في n8n

يوضح MicrosoftOAuth2Api.credentials.js المثبت:

Grant Type: authorizationCode

و:

{
    displayName: 'Authentication',
    name: 'authentication',
    type: 'hidden',
    default: 'body',
}

لذلك يبدو أن n8n من المتوقع أن يرسل السر العميل في نص الطلب عند تبديل/تحديث الرمز.


في هذه النقطة، فهمي هو أن التدفق يصل إلى:

المتصفح
  ↓
مصادقة Microsoft
  ↓
رمز التفويض المرجع
  ↓
Nginx
  ↓
/rest/oauth2-credential/callback يصل إلى n8n
  ↓
n8n يعالج رد الاتصال / يبدل رمز التفويض
  ↓
فشل مصادقة العميل
  ↓
502 Bad Gateway

أود بشكل خاص أن أفهم لماذا يصل رد الاتصال للتفويض إلى n8n لكن تبديل الرمز يفشل، خاصة وأن معرف العميل والسر العميل من نفس تطبيق Entra يتم قبولهما من قبل نقطة نهاية رمز Microsoft عند الاختبار يدويًا من داخل الحاوية.

هل هناك طريقة لتفعيل السجل التفصيلي لرد الاتصال OAuth2/تبديل الرمز، أو فحص بأمان طلب /token الدقيق الذي تم إنشاؤه بواسطة n8n؟

هل واجه أي شخص سلوكًا مماثلًا مع بيانات اعتماد Microsoft Outlook OAuth2؟

ما رسالة الخطأ (إن وجدت)؟

يتلقى المتصفح:

502 Bad Gateway
Server: nginx

أظهرت سجلات n8n أيضًا:

فشل مصادقة العميل
(على سبيل المثال، عميل غير معروف، لم يتم تضمين أي مصادقة عميل،
أو طريقة مصادقة غير مدعومة).

Error: Client authentication failed
    at getAuthError (...)
    at ClientOAuth2.accessTokenRequest (...)
    at ClientOAuth2Token.refresh (...)
    at runRefresh (...)
    at refreshOrFetchToken (...)
    at retryWithNewToken (...)
    ...

OAuth2 callback failed

الخطأ محيّر بشكل خاص لأن معرف العميل والسر العميل نفسه يتم التحقق منهما بنجاح ضد نقطة نهاية رمز Microsoft عند الاختبار يدويًا من داخل حاوية n8n.

يرجى مشاركة سير عملك

لا يوجد سير عمل متضمن حتى الآن.

تحدث المشكلة أثناء إنشاء/اختبار بيانات اعتماد Microsoft Outlook OAuth2 المدمجة، قبل أن تتمكن من استخدام عقدة Outlook في سير عمل.

شارك الإخراج الذي تعيده العقدة الأخيرة

غير قابل للتطبيق.

يحدث الفشل أثناء اتصال بيانات اعتماد Microsoft Outlook OAuth2، قبل تنفيذ سير العمل/العقدة.

معلومات حول إعداد n8n الخاص بك

  • إصدار n8n: 2.34.4

  • قاعدة البيانات (الافتراضي: SQLite): SQLite

  • إعداد N8N EXECUTIONS_PROCESS (الافتراضي: own, main): الافتراضي / غير مكوّن بشكل صريح

  • تشغيل n8n عبر (Docker, npm, n8n cloud, desktop app): Docker، مستضاف ذاتيًا

  • نظام التشغيل: Linux

متغيرات البيئة ذات الصلة:

N8N_EDITOR_BASE_URL=https://n8n.example.com
N8N_PROXY_HOPS=1
N8N_HOST=0.0.0.0
N8N_SECURE_COOKIE=false
N8N_PROTOCOL=https
WEBHOOK_URL=https://n8n.example.com

الهندسة المعمارية:

الإنترنت / المتصفح
        ↓ HTTPS
خادم وكيل عكسي Nginx
        ↓ HTTP :5678
مضيف Docker
        ↓
حاوية n8n

بيئة Microsoft:

Microsoft 365 / Entra ID
بيئة هجينة
صندوق بريد المستخدم
تسجيل تطبيق Entra مخصص لـ n8n
أذونات Microsoft Graph المفوضة
موافقة المسؤول الممنوحة

يمكنني توفير تكوين Nginx المُعقّم إضافيًا، أو تكوين Docker Compose، أو التقاط tcpdump، أو سجلات n8n إذا كان ذلك سيساعد في تشخيص المشكلة.

مرحبا @fakher، بينما تنتظر الرد، إليك بعض الأشياء التي قد تساعدك:

الموارد المقترحة

تم مطابقتها تلقائيًا مع سؤالك.

المستندات:

المنتدى:

@mohamed3nan, @schaepdlx, @Mookie_Lian - لقد ساعدتم في حل مشاكل مماثلة من قبل، هل يمكنكم الاطلاع على هذا؟

يقترحه تلقائيًا روبوت مجتمع n8n. إنه مشروع تجريبي - يرجى مشاركة ملاحظاتك هنا.

كتابة رائعة – لقد حددت المشكلة بشكل جيد. السبب الرئيسي هو على الأرجح فقدان ملف تعريف الارتباط الخاص بحالة OAuth بين إعادة التوجيه المصرح والرد، مما يتسبب في محاولة n8n تبديل الرمز بدون سياق بيانات اعتماد – وبالتالي “فشل المصادقة الخاصة بالعميل” من Microsoft على الرغم من أن معرّف العميل/السر صحيح.

السبب الجذري: N8N_SECURE_COOKIE=false + N8N_PROTOCOL=https

يخزن n8n حالة OAuth (بيانات اعتماد أي يتم توصيلها، معرّف العميل/السر الخاص بها) في ملف تعريف ارتباط الجلسة أثناء “ربط حسابي”. مع N8N_PROTOCOL=https، يجب أن يحدد n8n ملف تعريف الارتباط هذا SameSite=None; Secure. مع N8N_SECURE_COOKIE=false، تصدر بعض الإصدارات SameSite=None بدون Secure – وهو ما يحذفه Chrome 80+ صامتًا على HTTPS وفقًا لمواصفات SameSite.

عندما يعيد Microsoft التوجيه إلى /rest/oauth2-credential/callback، يكون ملف تعريف الارتباط الخاص بالحالة قد اختفى، لا يمكن لـ n8n العثور على بيانات الاعتماد المعلقة، يتم تبديل الرمز بسر عميل فارغ، يعود Microsoft مع “فشل مصادقة العميل”، ينهار n8n، ترى Nginx إعادة تعيين الاتصال، 502.

إن tcpdump “إعادة تعيين الاتصال حول معالجة الرد” هي بالضبط ما تبدو عليه استثناءات n8n التي لم تتم معالجتها من جانب الوكيل.

الإصلاحات بالترتيب:

  1. أزل N8N_SECURE_COOKIE=false – دع n8n يشتق أمان ملف تعريف الارتباط من N8N_PROTOCOL. مع N8N_PROTOCOL=https سيصدر بشكل صحيح ملفات تعريف ارتباط Secure التي تعيدها المتصفحات على إعادة التوجيه من Microsoft.

  2. قم بتفعيل N8N_LOG_LEVEL=debug مؤقتًا – ستشاهد طلب الرمز الدقيق الذي يرسله n8n إلى Microsoft، بما في ذلك ما إذا كانت client_id و redirect_uri مأهولة وقت التبديل.

  3. تحقق من أن WEBHOOK_URL و N8N_EDITOR_BASE_URL تطابقان Entra redirect URI الخاص بك بالضبط – يقوم n8n بتشفير عنوان URL للرد في حالة OAuth وأي عدم تطابق في حرف واحد (الشرطة المائلة الزائدة، http مقابل https) يتسبب في رفض Microsoft لتبديل الرمز.

  4. فحص تحقق: استخدم curl /rest/settings من خلال Nginx وتأكد من أنها تعيد https://n8n.example.com كعنوان URL للمثيل، وليس عنوان IP داخلي. إذا اعتقد n8n أن عنوانه الخاص مختلف، فإن حالة OAuth تشفر عنوان URL للرد غير الصحيح.

هذا محبط لأن نافذة الفشل صغيرة جدًا (ملف تعريف الارتباط الخاص بالحالة يعيش فقط لجولة إعادة التوجيه) ولا توجد أي رسالة خطأ مرئية حتى يتم تشغيل تسجيل تصحيح الأخطاء. إذا واجهت عقبة أو كنت تريد شخصًا يتعامل مع تكوين n8n الموجود على الخوادم الخاصة بك من البداية إلى النهاية، فهذا ما نفعله في Automation Services — Occelatus Labs – لكن الخطوات أعلاه يجب أن توصلك إلى هناك.

تتبع المكدس (Stack trace) هو الشيء الأكثر فائدة في منشورك وأعتقد أنه يشير إلى مكان مختلف عما كنت تبحث عنه.

ClientOAuth2Token.refresh في runRefresh في refreshOrFetchToken يعني أن n8n على مسار التحديث وليس على مسار تبادل رمز التفويض لأول مرة. لذا فهو لا يفشل في تبديل الرمز الجديد الخاص بك، بل يحاول التحديث مقابل سجل بيانات اعتماد موجود ولا يحتوي على أي شيء قابل للاستخدام. يترتب على ذلك أمران. مطاردة nginx ربما تكون طريقاً مسدوداً، لأن خطأ 502 هو nginx يبلغ عن وفاة الاتصال الأعلى عندما أسقط الخطأ غير المعالج الطلب، وهذا عرض وليس السبب الأساسي. وإعادة النقر على Connect على نفس بيانات الاعتماد يمكن أن تبقيك على نفس المسار، لذا احذف بيانات الاعتماد بالكامل وأنشئ واحدة جديدة بدلاً من إعادة توصيل الواحدة الموجودة.

الشيء الآخر الذي يستحق الفحص، والمشتبه به الرئيسي لديّ بناءً على صيغة الخطأ الدقيقة، هو أي نظام أساسي تم تسجيل معرّف URI إعادة التوجيه تحته في تسجيل تطبيق Entra. يجب أن يكون Web. إذا كان معرّف URI هذا موجوداً ضمن Single-page application، فإن Entra يتعامل مع التطبيق كعميل عام ويرفض مصادقة client_secret عند تبادل الرمز بالنص الدقيق لطريقة المصادقة غير المدعومة. الاختبار اليدوي الخاص بك لن يلتقط هذا، لأن client_credentials هو تدفق عميل سري ويتم تقييمه بشكل مختلف عن authorization_code مقابل تطبيق SPA.

حول سؤال التسجيل، N8N_LOG_LEVEL=debug على الحاوية سيعطيك تفاصيل طلب الرمز التي تبحث عنها.