אימות באמצעות OpenID Connect בפלטפורמות של Apple

אם שדרגתם ל-Firebase Authentication with Identity Platform, אתם יכולים לאמת את המשתמשים שלכם באמצעות Firebase באמצעות ספק תואם OpenID Connect‏ (OIDC) לפי בחירתכם. כך אפשר להשתמש בספקי זהויות שלא נתמכים באופן טבעי על ידי Firebase.

לפני שמתחילים

כדי להשתמש בספק OIDC כדי לאפשר למשתמשים להיכנס, צריך קודם לאסוף מהספק מידע מסוים:

  • מזהה לקוח: מחרוזת ייחודית לספק שמזהה את האפליקציה שלכם. יכול להיות שהספק יקצה לכם מזהה לקוח שונה לכל פלטפורמה שאתם תומכים בה. זהו אחד מהערכים של ההצהרה aud באסימוני הזהות שהונפקו על ידי הספק.

  • סוד הלקוח: מחרוזת סודית שהספק משתמש בה כדי לאשר את הבעלות על Client-ID. לכל מזהה לקוח צריך להיות סוד לקוח תואם. (הערך הזה נדרש רק אם משתמשים בתהליך קוד האימות, שמומלץ מאוד).

  • המוסד המנפיק: מחרוזת שמזהה את הספק. הערך הזה צריך להיות כתובת URL שאם מוסיפים לה את /.well-known/openid-configuration, היא הופכת למיקום של מסמך הגילוי של ספק OIDC. לדוגמה, אם המנפיק הוא https://auth.example.com, מסמך הגילוי צריך להיות זמין בכתובת https://auth.example.com/.well-known/openid-configuration.

אחרי שיש לכם את הפרטים שלמעלה, אתם יכולים להפעיל את OpenID Connect כספק כניסה לפרויקט Firebase:

  1. איך מוסיפים את Firebase לפרויקט iOS

  2. אם לא שדרגתם ל-Firebase Authentication with Identity Platform, עליכם לעשות זאת. אימות OpenID Connect זמין רק בפרויקטים משודרגים.

  3. בדף Sign-in providers (ספקי כניסה) במסוף Firebase, לוחצים על Add new provider (הוספת ספק חדש) ואז על OpenID Connect.

  4. בוחרים אם להשתמש בתהליך קוד הרשאה או בתהליך הרשאה מרומזת.

    מומלץ להשתמש תמיד בתהליך קבלת הרשאה אם הספק תומך בו. זרם הענקת גישה משתמע פחות מאובטח, ולא מומלץ להשתמש בו.

  5. נותנים שם לספק. רושמים את מזהה הספק שנוצר: משהו כמו oidc.example-provider. תצטרכו את המזהה הזה כשתוסיפו קוד להתחברות לאפליקציה.

  6. מציינים את מזהה הלקוח, את סוד הלקוח ואת מחרוזת המנפיק של הספק. הערכים האלה צריכים להיות זהים בדיוק לערכים שהספק הקצה לכם.

  7. שומרים את השינויים.

טיפול בתהליך הכניסה באמצעות Firebase SDK

הדרך הכי קלה לאמת את המשתמשים שלכם באמצעות Firebase באמצעות ספק OIDC היא לטפל בתהליך הכניסה כולו באמצעות Firebase SDK.

כדי לטפל בתהליך הכניסה באמצעות Firebase Apple platforms SDK, פועלים לפי השלבים הבאים:

  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 Realtime Database וב-Cloud Storage Security Rules, אפשר לקבל את מזהה המשתמש הייחודי של המשתמש המחובר מהמשתנה 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;
}

כדאי גם להוסיף קוד לטיפול בשגיאות עבור כל השגיאות שקשורות לאימות. מידע נוסף זמין במאמר בנושא טיפול בשגיאות.