المصادقة باستخدام OpenID Connect في تطبيقات الويب

إذا كنت قد أجريت ترقية إلى Firebase Authentication with Identity Platform، يمكنك مصادقة المستخدمين باستخدام Firebase من خلال موفِّر متوافق مع OpenID Connect (OIDC) من اختيارك. ويتيح ذلك استخدام موفّري الهوية غير المتوافقين أصلاً مع Firebase.

قبل البدء

لتسجيل دخول المستخدمين باستخدام موفِّر OIDC، عليك أولاً جمع بعض المعلومات من الموفِّر:

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

  • سر العميل: هو سلسلة سرية يستخدمها مقدّم الخدمة لتأكيد ملكية معرّف العميل. لكل معرّف عميل، ستحتاج إلى سر عميل مطابق. (هذه القيمة مطلوبة فقط إذا كنت تستخدم مسار رمز التفويض، وهو مسار يُنصح به بشدة.)

  • جهة الإصدار: هي سلسلة تحدّد موفّر الخدمة. يجب أن تكون هذه القيمة عنوان URL يشير عند إلحاقه بـ /.well-known/openid-configuration إلى موقع مستند الاستكشاف الخاص بمقدّم الخدمة لـ OIDC. على سبيل المثال، إذا كان جهة الإصدار هي https://auth.example.com، يجب أن يكون مستند الاكتشاف متاحًا على https://auth.example.com/.well-known/openid-configuration.

بعد الحصول على المعلومات المذكورة أعلاه، فعِّل OpenID Connect كموفّر تسجيل دخول لمشروع Firebase الخاص بك:

  1. أضِف Firebase إلى مشروع JavaScript.

  2. إذا لم تتم الترقية إلى Firebase Authentication with Identity Platform، يُرجى إجراء ذلك، لأنّ مصادقة OpenID Connect متاحة فقط في المشاريع التي تمت ترقيتها.

  3. في وحدة تحكّم Firebase، انتقِل إلى الأمان > المصادقة.

  4. في علامة التبويب طريقة تسجيل الدخول، انقر على إضافة موفّر جديد، ثم انقر على OpenID Connect.

  5. اختَر ما إذا كنت ستستخدم مسار رمز التفويض أو مسار منح الإذن الضمني.

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

  6. يُرجى إدخال اسم لمقدّم الخدمة هذا. دوِّن معرّف الموفّر الذي تم إنشاؤه، مثل oidc.example-provider. ستحتاج إلى هذا المعرّف عند إضافة رمز تسجيل الدخول إلى تطبيقك.

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

  8. احفظ التغييرات.

التعامل مع عملية تسجيل الدخول باستخدام حزمة تطوير البرامج (SDK) من Firebase

أسهل طريقة لمصادقة المستخدمين باستخدام Firebase من خلال موفّر OIDC هي التعامل مع عملية تسجيل الدخول بأكملها باستخدام حزمة تطوير البرامج (SDK) من Firebase.

للتعامل مع عملية تسجيل الدخول باستخدام حزمة تطوير البرامج (SDK) من Firebase JavaScript، اتّبِع الخطوات التالية:

  1. أنشئ مثيلاً من OAuthProvider باستخدام معرّف الموفّر الذي حصلت عليه في وحدة تحكّم Firebase.

    Web

    import { OAuthProvider } from "firebase/auth";
    
    const provider = new OAuthProvider('oidc.example-provider');
    

    Web

    var provider = new firebase.auth.OAuthProvider('oidc.example-provider');
    
  2. اختياري: حدِّد مَعلمات OAuth مخصّصة إضافية تريد إرسالها مع طلب OAuth.

    Web

    provider.setCustomParameters({
      // Target specific email with login hint.
      login_hint: 'user@example.com'
    });
    

    Web

    provider.setCustomParameters({
      // Target specific email with login hint.
      login_hint: 'user@example.com'
    });
    

    يُرجى التواصل مع مقدّم الخدمة لمعرفة المَعلمات التي يتيحها. يُرجى العِلم أنّه لا يمكنك تمرير المَعلمات المطلوبة في Firebase باستخدام setCustomParameters. هذه المَعلَمات هي client_id وresponse_type وredirect_uri وstate وscope وresponse_mode.

  3. اختياري: حدِّد نطاقات إضافية لبروتوكول OAuth 2.0 تتجاوز الملف الشخصي الأساسي الذي تريد طلبه من موفّر المصادقة.

    Web

    provider.addScope('mail.read');
    provider.addScope('calendars.read');
    

    Web

    provider.addScope('mail.read');
    provider.addScope('calendars.read');
    

    يمكنك الرجوع إلى مقدّم الخدمة لمعرفة النطاقات التي يتيحها.

  4. يمكنك المصادقة باستخدام Firebase من خلال عنصر موفّر OAuth.

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

    مسار إعادة التوجيه

    إعادة التوجيه إلى صفحة تسجيل الدخول الخاصة بمقدّم الخدمة من خلال طلب signInWithRedirect():

    Web

    import { getAuth, signInWithRedirect } from "firebase/auth";
    
    const auth = getAuth();
    signInWithRedirect(auth, provider);
    

    Web

    firebase.auth().signInWithRedirect(provider);
    

    بعد أن يكمل المستخدم عملية تسجيل الدخول ويعود إلى تطبيقك، يمكنك الحصول على نتيجة تسجيل الدخول من خلال استدعاء getRedirectResult().

    Web

    import { getAuth, getRedirectResult, OAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    getRedirectResult(auth)
      .then((result) => {
        // User is signed in.
        // IdP data available in result.additionalUserInfo.profile.
    
        // Get the OAuth access token and ID Token
        const credential = OAuthProvider.credentialFromResult(result);
        const accessToken = credential.accessToken;
        const idToken = credential.idToken;
      })
      .catch((error) => {
        // Handle error.
      });
    

    Web

    firebase.auth().getRedirectResult()
      .then((result) => {
        // IdP data available in result.additionalUserInfo.profile.
        // ...
    
        /** @type {firebase.auth.OAuthCredential} */
        var credential = result.credential;
    
        // OAuth access and id tokens can also be retrieved:
        var accessToken = credential.accessToken;
        var idToken = credential.idToken;
      })
      .catch((error) => {
        // Handle error.
      });
    

    مسار النوافذ المنبثقة

    Web

    import { getAuth, signInWithPopup, OAuthProvider } from "firebase/auth";
    
    const auth = getAuth();
    signInWithPopup(auth, provider)
      .then((result) => {
        // User is signed in.
        // IdP data available using getAdditionalUserInfo(result)
    
        // Get the OAuth access token and ID Token
        const credential = OAuthProvider.credentialFromResult(result);
        const accessToken = credential.accessToken;
        const idToken = credential.idToken;
      })
      .catch((error) => {
        // Handle error.
      });
    

    Web

    firebase.auth().signInWithPopup(provider)
      .then((result) => {
        // IdP data available in result.additionalUserInfo.profile.
        // ...
    
        /** @type {firebase.auth.OAuthCredential} */
        var credential = result.credential;
    
        // OAuth access and id tokens can also be retrieved:
        var accessToken = credential.accessToken;
        var idToken = credential.idToken;
      })
      .catch((error) => {
        // Handle error.
      });
    
  5. في حين تركّز الأمثلة أعلاه على عمليات تسجيل الدخول، يمكنك استخدام النمط نفسه لربط موفّر OIDC بمستخدم حالي باستخدام linkWithRedirect() وlinkWithPopup()، وإعادة مصادقة مستخدم باستخدام reauthenticateWithRedirect() وreauthenticateWithPopup()، ويمكن استخدام ذلك لاسترداد بيانات اعتماد جديدة للعمليات الحسّاسة التي تتطلّب تسجيل دخول حديث.

التعامل مع عملية تسجيل الدخول يدويًا

إذا سبق لك تنفيذ مسار تسجيل الدخول باستخدام OpenID Connect في تطبيقك، يمكنك استخدام رمز التعريف مباشرةً للمصادقة مع Firebase:

Web

import { getAuth, signInWithCredential, OAuthProvider } from "firebase/auth";

const provider = new OAuthProvider("oidc.example-provider");
const credential = provider.credential({
    idToken: idToken,
});
signInWithCredential(getAuth(), credential)
    .then((result) => {
        // User is signed in.
        // IdP data available in result.additionalUserInfo.profile.

        // Get the OAuth access token and ID Token
        const credential = OAuthProvider.credentialFromResult(result);
        const accessToken = credential.accessToken;
        const idToken = credential.idToken;
    })
    .catch((error) => {
        // Handle error.
    });

Web

const provider = new OAuthProvider("oidc.example-provider");
const credential = provider.credential({
    idToken: idToken,
});
firebase.auth().signInWithCredential(credential)
    .then((result) => {
        // User is signed in.
        // IdP data available in result.additionalUserInfo.profile.

        // Get the OAuth access token and ID Token
        const credential = OAuthProvider.credentialFromResult(result);
        const accessToken = credential.accessToken;
        const idToken = credential.idToken;
    })
    .catch((error) => {
        // Handle error.
    });