المصادقة باستخدام OpenID Connect على أنظمة Apple الأساسية

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

قبل البدء

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

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

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

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

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

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

  2. إذا لم يسبق لك الترقية إلى مصادقة Firebase باستخدام النظام الأساسي للهوية، لا تتوفر مصادقة OpenID Connect إلا في المشاريع التي تمت ترقيتها.

  3. في صفحة موفِّرو خدمات تسجيل الدخول ضمن "وحدة تحكُّم Firebase"، انقر على إضافة موفِّر جديد، ثم انقر على OpenID Connect.

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

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

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

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

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

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

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

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

  1. إضافة مخططات عناوين URL مخصصة إلى مشروع Xcode:

    1. افتح إعدادات المشروع: انقر مرّتين على اسم المشروع في العرض التدرّجي الأيمن. اختَر تطبيقك من القسم الاستهدافات، ثم اختَر علامة التبويب المعلومات، ووسِّع القسم أنواع عناوين URL.
    2. انقر على الزر + وأضِف رقم تعريف التطبيق المشفر كمخطط عنوان URL. يمكنك العثور على رقم تعريف التطبيق المرمّز في صفحة الإعدادات العامة ضمن "وحدة تحكُّم Firebase" ضمن قسم تطبيق iOS. واترك الحقول الأخرى فارغة.

      عند اكتمال العملية، من المفترض أن تظهر الإعدادات بشكل مشابه لما يلي (ولكن مع القيم الخاصة بالتطبيق):

      لقطة شاشة لواجهة إعداد مخطط عنوان URL المخصّص في Xcode
  2. أنشِئ نسخة افتراضية من OAuthProvider باستخدام رقم تعريف الموفّر الذي حصلت عليه في "وحدة تحكُّم Firebase".

    Swift

    var provider = OAuthProvider(providerID: "oidc.example-provider")
    

    Objective-C

    FIROAuthProvider *provider = [FIROAuthProvider providerWithProviderID:@"oidc.example-provider"];
    
  3. اختياري: حدِّد مَعلمات OAuth المخصّصة الإضافية التي تريد إرسالها مع طلب OAuth.

    Swift

    provider.customParameters = [
      "login_hint": "user@example.com"
    ]
    

    Objective-C

    [provider setCustomParameters:@{@"login_hint": @"user@example.com"}];
    

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

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

    Swift

    provider.scopes = ["mail.read", "calendars.read"]
    

    Objective-C

    [provider setScopes:@[@"mail.read", @"calendars.read"]];
    

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

  5. اختياري: إذا أردت تخصيص طريقة عرض تطبيقك للسمة SFSafariViewController أو UIWebView عند عرض reCAPTCHA للمستخدم، أنشئ فئة مخصّصة تتوافق مع بروتوكول AuthUIDelegate.

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

    Swift

    // If you created a custom class that conforms to AuthUIDelegate,
    // pass it instead of nil:
    provider.getCredentialWith(nil) { credential, error in
      if error != nil {
        // Handle error.
      }
      if credential != nil {
        Auth().signIn(with: credential) { authResult, error in
          if error != nil {
            // Handle error.
          }
          // User is signed in.
          // IdP data available in authResult.additionalUserInfo.profile.
          // OAuth access token can also be retrieved:
          // (authResult.credential as? OAuthCredential)?.accessToken
          // OAuth ID token can also be retrieved:
          // (authResult.credential as? OAuthCredential)?.idToken
        }
      }
    }
    

    Objective-C

    // If you created a custom class that conforms to AuthUIDelegate,
    // pass it instead of nil:
    [provider getCredentialWithUIDelegate:nil
                                completion:^(FIRAuthCredential *_Nullable credential, NSError *_Nullable error) {
      if (error) {
        // Handle error.
      }
      if (credential) {
        [[FIRAuth auth] signInWithCredential:credential
                                  completion:^(FIRAuthDataResult *_Nullable authResult, NSError *_Nullable error) {
          if (error) {
            // Handle error.
          }
          // User is signed in.
          // IdP data available in authResult.additionalUserInfo.profile.
          // OAuth access token can also be retrieved:
          // ((FIROAuthCredential *)authResult.credential).accessToken
          // OAuth ID token can also be retrieved:
          // ((FIROAuthCredential *)authResult.credential).idToken
        }];
      }
    }];
    
  7. مع أنّ الأمثلة أعلاه تركّز على مسارات تسجيل الدخول، يمكنك أيضًا ربط موفِّر OIDC بمستخدم حالي باستخدام linkWithCredential. على سبيل المثال، يمكنك ربط عدة مقدمي بالمستخدم نفسه مما يسمح لهم بتسجيل الدخول باستخدام أي منهما.

    Swift

    Auth().currentUser.link(withCredential: credential) { authResult, error in
      if error != nil {
        // Handle error.
      }
      // OIDC credential is linked to the current user.
      // IdP data available in authResult.additionalUserInfo.profile.
      // OAuth access token can also be retrieved:
      // (authResult.credential as? OAuthCredential)?.accessToken
      // OAuth ID token can also be retrieved:
      // (authResult.credential as? OAuthCredential)?.idToken
    }
    

    Objective-C

    [[FIRAuth auth].currentUser
        linkWithCredential:credential
                completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
      if (error) {
        // Handle error.
      }
      // OIDC credential is linked to the current user.
      // IdP data available in authResult.additionalUserInfo.profile.
      // OAuth access token can also be retrieved:
      // ((FIROAuthCredential *)authResult.credential).accessToken
      // OAuth ID token can also be retrieved:
      // ((FIROAuthCredential *)authResult.credential).idToken
    }];
    
  8. يمكن استخدام النمط نفسه مع reauthenticateWithCredential الذي يمكن استخدامه لاسترداد بيانات الاعتماد الجديدة للعمليات الحسّاسة التي تتطلب تسجيل دخول حديث.

    Swift

    Auth().currentUser.reauthenticateWithCredential(withCredential: credential) { authResult, error in
      if error != nil {
        // Handle error.
      }
      // User is re-authenticated with fresh tokens minted and
      // should be able to perform sensitive operations like account
      // deletion and email or password update.
      // IdP data available in result.additionalUserInfo.profile.
      // Additional OAuth access token can also be retrieved:
      // (authResult.credential as? OAuthCredential)?.accessToken
      // OAuth ID token can also be retrieved:
      // (authResult.credential as? OAuthCredential)?.idToken
    }
    

    Objective-C

    [[FIRAuth auth].currentUser
        reauthenticateWithCredential:credential
                          completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
      if (error) {
        // Handle error.
      }
      // User is re-authenticated with fresh tokens minted and
      // should be able to perform sensitive operations like account
      // deletion and email or password update.
      // IdP data available in result.additionalUserInfo.profile.
      // Additional OAuth access token can also be retrieved:
      // ((FIROAuthCredential *)authResult.credential).accessToken
      // OAuth ID token can also be retrieved:
      // ((FIROAuthCredential *)authResult.credential).idToken
    }];
    

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

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

Swift

let credential = OAuthProvider.credential(
    withProviderID: "oidc.example-provider",  // As registered in Firebase console.
    idToken: idToken,  // ID token from OpenID Connect flow.
    rawNonce: nil
)
Auth.auth().signIn(with: credential) { authResult, error in
    if error {
        // Handle error.
        return
    }
    // User is signed in.
    // IdP data available in authResult?.additionalUserInfo?.profile
}

Objective-C

FIROAuthCredential *credential =
    [FIROAuthProvider credentialWithProviderID:@"oidc.example-provider"  // As registered in Firebase console.
                                       IDToken:idToken  // ID token from OpenID Connect flow.
                                      rawNonce:nil];
[[FIRAuth auth] signInWithCredential:credential
                          completion:^(FIRAuthDataResult * _Nullable authResult,
                                      NSError * _Nullable error) {
    if (error != nil) {
        // Handle error.
        return;
    }
    // User is signed in.
    // IdP data available in authResult.additionalUserInfo.profile
}];

الخطوات اللاحقة

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

  • في تطبيقاتك، يمكنك الحصول على معلومات الملف الشخصي الأساسية للمستخدم من العنصر User . راجع إدارة المستخدمين.

  • في قاعدة بيانات Firebase في الوقت الفعلي وقواعد أمان Cloud Storage، يمكنك الحصول على رقم تعريف المستخدم الفريد للمستخدم الذي سجّل الدخول من المتغيّر auth واستخدامه للتحكّم في البيانات التي يمكن للمستخدم الوصول إليها.

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

لتسجيل خروج مستخدم، يُرجى الاتصال بالرقم signOut:.

Swift

let firebaseAuth = Auth.auth()
do {
  try firebaseAuth.signOut()
} catch let signOutError as NSError {
  print("Error signing out: %@", signOutError)
}

Objective-C

NSError *signOutError;
BOOL status = [[FIRAuth auth] signOut:&signOutError];
if (!status) {
  NSLog(@"Error signing out: %@", signOutError);
  return;
}

يمكنك أيضًا إضافة رمز معالجة الأخطاء إلى المجموعة الكاملة من أخطاء المصادقة. يُرجى الاطّلاع على التعامل مع الأخطاء.