أفضل الممارسات لاستخدام ميزةsignInWithRedirect في المتصفّحات التي تحظر إمكانية الوصول إلى مساحة تخزين الجهات الخارجية

يتناول هذا المستند أفضل الممارسات لاستخدام عمليات إعادة توجيه عمليات تسجيل الدخول على المتصفّحات التي تحظر ملفات تعريف الارتباط التابعة لجهات خارجية. يجب اتّباع أحد الخيارات المذكورة هنا لكي تعمل signInWithRedirect() على النحو المنشود في بيئات الإنتاج في جميع المتصفّحات.

نظرة عامة

لجعل سير عمل signInWithRedirect() سلسًا لك ولمستخدميك، تستخدم حزمة تطوير برامج (SDK) JavaScript لمصادقة Firebase إطار iframe من مصادر متعددة يتصل بنطاق "استضافة Firebase" لتطبيقك. إلا أنّ هذه الآلية لا تعمل مع المتصفّحات التي تحظر الوصول إلى مساحة تخزين تابعة لجهات خارجية.

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

  • إذا كنت تستضيف تطبيقك باستخدام "استضافة Firebase" على نطاق فرعي من firebaseapp.com، لن تتأثر بهذه المشكلة وليس عليك اتّخاذ أي إجراء.
  • إذا كنت تستضيف تطبيقك باستخدام "استضافة Firebase" على نطاق خاص أو نطاق فرعي من web.app، استخدِم الخيار 1.
  • إذا كنت تستضيف تطبيقك باستخدام خدمة غير Firebase، استخدِم الخيار 2 أو الخيار 3 أو الخيار 4 أو الخيار 5.

الخيار 1: تعديل إعدادات Firebase لاستخدام نطاقك الخاص باعتباره authDomain

إذا كنت تستضيف تطبيقك من خلال "استضافة Firebase" باستخدام نطاق خاص، يمكنك ضبط حزمة تطوير البرامج (SDK) لمنصّة Firebase لاستخدام نطاقك الخاص باسم authDomain. يضمن ذلك أن تطبيقك وإطار iframe للمصادقة يستخدمان النطاق نفسه، ما يمنع مشكلة تسجيل الدخول. (إذا كنت لا تستخدم "استضافة Firebase"، ستحتاج إلى استخدام خيار مختلف). تأكَّد من إعداد النطاق الخاص في المشروع نفسه الذي تستخدمه للمصادقة.

لتعديل إعداد Firebase لاستخدام نطاقك الخاص كنطاق مصادقة، عليك إجراء ما يلي:

  1. اضبط حزمة تطوير برامج JavaScript JS من Firebase لاستخدام نطاقك الخاص باسم authDomain:

    const firebaseConfig = {
      apiKey: "<api-key>",
      authDomain: "<the-domain-that-serves-your-app>",
      databaseURL: "<database-url>",
      projectId: "<project-id>",
      appId: "<app-id>"
    };
    
  1. أضِف authDomain الجديد إلى قائمة معرّفات الموارد المنتظمة (URI) المعتمَدة لإعادة التوجيه لدى موفِّر بروتوكول OAuth. وتعتمد كيفية إجراء ذلك على موفّر الخدمة، ولكن بشكل عام، يمكنك اتّباع القسم "قبل البدء" لدى أي موفِّر للحصول على التعليمات المحدَّدة (على سبيل المثال، موفِّر خدمة Facebook). يبدو أنّ معرِّف الموارد المنتظم (URI) المعدَّل للتفويض هو https://<the-domain-that-serves-your-app>/__/auth/handler، ويعني /__/auth/handler اللاحقة المهمة.

    وبالمثل، إذا كنت تستخدم موفّر SAML، أضِف authDomain الجديد إلى عنوان URL لخدمة مستهلكي تأكيد بيانات SAML (ACS).

  2. تأكَّد من أنّ continue_uri في قائمة النطاقات المعتمَدة.

  3. يمكنك إعادة النشر باستخدام "استضافة Firebase" إذا لزم الأمر لاسترجاع أحدث ملف إعداد Firebase تتم استضافته على /__/firebase/init.json.

الخيار 2: الانتقال إلى SignInWithPopup()

استخدِم signInWithPopup() بدلاً من signInWithRedirect(). تبقى بقية رموز تطبيقك كما هي، ولكن يتم استرداد الكائن UserCredential بشكل مختلف.

واجهة برمجة التطبيقات Web modular API

  // Before
  // ==============
  signInWithRedirect(auth, new GoogleAuthProvider());
  // After the page redirects back
  const userCred = await getRedirectResult(auth);

  // After
  // ==============
  const userCred = await signInWithPopup(auth, new GoogleAuthProvider());

واجهة برمجة التطبيقات لمساحة الاسم على الويب

  // Before
  // ==============
  firebase.auth().signInWithRedirect(new firebase.auth.GoogleAuthProvider());
  // After the page redirects back
  var userCred = await firebase.auth().getRedirectResult();

  // After
  // ==============
  var userCred = await firebase.auth().signInWithPopup(
      new firebase.auth.GoogleAuthProvider());
```

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

الخيار 3: طلبات مصادقة الخادم الوكيل إلى firebaseapp.com

يبدأ مسار signInWithRedirect بإعادة التوجيه من نطاق تطبيقك إلى النطاق المحدّد في المعلمة authDomain في إعداد firebase (".firebaseapp.com" تلقائيًا). يستضيف authDomain الرمز المساعد لتسجيل الدخول الذي يعيد التوجيه إلى موفّر الهوية، والذي يؤدي بنجاح إلى إعادة التوجيه إلى نطاق التطبيق.

عند عودة مسار المصادقة إلى نطاق تطبيقك، يتم الوصول إلى مساحة التخزين في المتصفّح الخاصة بنطاق مساعد تسجيل الدخول. يؤدّي هذا الخيار والخيار التالي (للاستضافة الذاتية للرمز البرمجي) إلى إلغاء إمكانية الوصول إلى مساحة التخزين من مصادر متعددة، والتي تحظرها المتصفّحات.

  1. عليك إعداد خادم وكيل عكسي على خادم تطبيقك لتتم إعادة توجيه طلبات GET/POST إلى https://<app domain>/__/auth/ إلى https://<project>.firebaseapp.com/__/auth/. يُرجى التأكد من أنّ عملية إعادة التوجيه هذه تكون شفافة بالنسبة إلى المتصفّح، وأنّه لا يمكن إجراء ذلك من خلال عملية إعادة التوجيه 302.

    إذا كنت تستخدم nginx، لعرض نطاقك المخصص، ستبدو تهيئة الخادم الوكيل العكسي على النحو التالي:

    # reverse proxy for signin-helpers for popup/redirect sign in.
    location /__/auth {
      proxy_pass https://<project>.firebaseapp.com;
    }
    
  2. اتّبِع الخطوات الواردة في الخيار 1 لتعديل redirect_uri وعنوان URL لـ ACS وauthDomain. بعد إعادة نشر تطبيقك، من المفترض ألا يتم الوصول إلى التخزين من مصادر متعددة.

الخيار 4: إجراء استضافة ذاتية لرمز مساعد تسجيل الدخول في نطاقك

هناك طريقة أخرى لإزالة إمكانية الوصول إلى مساحة التخزين المشتركة المصدر، وهي إجراء الاستضافة الذاتية لرمز مساعد تسجيل الدخول إلى Firebase. ومع ذلك، لا تعمل هذه الطريقة عند تسجيل الدخول إلى Apple أو SAML. لا تستخدم هذا الخيار إلا إذا لم يكن إعداد الخادم الوكيل العكسي في الخيار 3 ممكنًا.

تتضمّن عملية استضافة الرمز المساعِد الخطوات التالية:

  1. نزِّل الملفات المطلوب استضافتها من موقع <project>.firebaseapp.com عن طريق تنفيذ الأوامر التالية:

    mkdir signin_helpers/ && cd signin_helpers
    wget https://<project>.firebaseapp.com/__/auth/handler
    wget https://<project>.firebaseapp.com/__/auth/handler.js
    wget https://<project>.firebaseapp.com/__/auth/experiments.js
    wget https://<project>.firebaseapp.com/__/auth/iframe
    wget https://<project>.firebaseapp.com/__/auth/iframe.js
    wget https://<project>.firebaseapp.com/__/firebase/init.json
    
  2. استضِف الملفات المذكورة أعلاه ضمن نطاق تطبيقك. تأكَّد من أنّ خادم الويب يمكنه الاستجابة إلى https://<app domain>/__/auth/<filename> و https://<app domain>/__/firebase/init.json.

    في ما يلي نموذج لتنفيذ خادم يعمل على تنزيل الملفات ويستضيفها. ننصح بتنزيل الملفات ومزامنتها بشكل دوري لضمان الحصول على أحدث إصلاحات الأخطاء والميزات.

  3. اتّبِع الخطوات الواردة في الخيار 1 لتعديل redirect_uri وauthDomain المعتمدَين. بعد إعادة نشر تطبيقك، من المفترض ألا يتم الوصول إلى التخزين من مصادر متعددة.

الخيار 5: التعامل مع عملية تسجيل دخول مقدِّم الخدمة بشكل مستقل

توفّر حزمة تطوير البرامج (SDK) لمصادقة Firebase كلاً من signInWithPopup() وsignInWithRedirect() كطرق سهلة لاستيعاب المنطق المعقد وتجنُّب الحاجة إلى استخدام حزمة SDK أخرى. يمكنك تجنُّب استخدام أي من الطريقتين بالكامل عن طريق تسجيل الدخول بشكل مستقل إلى موفّر الخدمة، ثم استخدام signInWithCredential() لتبادل بيانات اعتماد موفِّر الخدمة لبيانات اعتماد مصادقة Firebase. على سبيل المثال، يمكنك استخدام حزمة تطوير البرامج (SDK) لتسجيل الدخول بحساب Google، ورمز نموذجي للحصول على بيانات اعتماد حساب Google، ثم إنشاء مثيل لبيانات اعتماد Google جديدة، وذلك عن طريق تشغيل الرمز التالي:

واجهة برمجة التطبيقات Web modular API

  // `googleUser` from the onsuccess Google Sign In callback.
  //  googUser = gapi.auth2.getAuthInstance().currentUser.get();
  const credential = GoogleAuthProvider.credential(googleUser.getAuthResponse().id_token);
  const result = await signInWithCredential(auth, credential);

واجهة برمجة التطبيقات لمساحة الاسم على الويب

  // `googleUser` from the onsuccess Google Sign In callback.
  const credential = firebase.auth.GoogleAuthProvider.credential(
      googleUser.getAuthResponse().id_token);
  const result = await firebase.auth().signInWithCredential(credential);

بعد طلب signInWithCredential()، تعمل بقية التطبيقات بنفس الطريقة التي كانت تعمل بها من قبل.

يمكنك الاطّلاع هنا على تعليمات الحصول على بيانات اعتماد Apple.