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

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

نظرة عامة

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

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

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

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

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

لتعديل إعدادات Firebase لاستخدام نطاقك الخاص كنطاق مصادقة، اتّبِع الخطوات التالية:

  1. اضبط حزمة تطوير البرامج (SDK) في Firebase JS لاستخدام نطاقك المخصّص على النحو التالي: authDomain:

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

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

  2. تأكَّد من أنّ continue_uri مدرَج في قائمة النطاقات المصرّح بها.

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

الخيار 2: التبديل إلى signInWithPopup()

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

Web

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

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

Web

  // 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 وACS URL و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/__/auth/links
    wget https://<project>.firebaseapp.com/__/auth/links.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) الخاصة بخدمة &quot;مصادقة Firebase&quot; الطريقتَين signInWithPopup() وsignInWithRedirect() كطريقتَين مناسبتَين لتضمين منطق معقّد وتجنُّب الحاجة إلى استخدام حزمة تطوير برامج (SDK) أخرى. يمكنك تجنُّب استخدام أي من الطريقتين تمامًا من خلال تسجيل الدخول بشكل مستقل إلى موفّر الخدمة، ثم استخدام signInWithCredential() لتبديل بيانات اعتماد موفّر الخدمة ببيانات اعتماد Firebase Authentication. على سبيل المثال، يمكنك استخدام حزمة تطوير البرامج (SDK) الخاصة بخدمة &quot;تسجيل الدخول باستخدام حساب Google&quot; نموذج الرمز البرمجي للحصول على بيانات اعتماد حساب Google، ثم إنشاء بيانات اعتماد جديدة من Google عن طريق تنفيذ الرمز البرمجي التالي:

Web

  // `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);

Web

  // `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.