אימות באמצעות כניסה באמצעות חשבון Google בפלטפורמות של Apple

כדי לאפשר למשתמשים לבצע אימות ב-Firebase באמצעות חשבונות Google שלהם, אפשר לשלב את 'כניסה באמצעות חשבון Google' באפליקציה.

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

שימוש ב-Swift Package Manager כדי להתקין ולנהל יחסי תלות ב-Firebase.

  1. ב-Xcode, כשפרויקט האפליקציה פתוח, עוברים אל קובץ > הוספת חבילות.
  2. כשמופיעה בקשה, מוסיפים את המאגר של Firebase SDK לפלטפורמות של Apple:
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. בוחרים את הספרייה Firebase Authentication.
  5. מוסיפים את הדגל -ObjC לקטע Other Linker Flags (דגלים אחרים של קישור) בהגדרות ה-build של היעד.
  6. בסיום, Xcode יתחיל לפתור את יחסי התלות ולהוריד אותם באופן אוטומטי ברקע.

הוספת Google Sign-In SDK לפרויקט

  1. ב-Xcode, כשפרויקט האפליקציה פתוח, עוברים אל קובץ > הוספת חבילות.

  2. כשמופיעה הבקשה, מוסיפים את המאגר של Google Sign-In SDK:

    https://github.com/google/GoogleSignIn-iOS
    
  3. בסיום, Xcode יתחיל לפתור את יחסי התלות ולהוריד אותם באופן אוטומטי ברקע.

הפעלת כניסה באמצעות חשבון Google בפרויקט Firebase

כדי לאפשר למשתמשים להיכנס באמצעות 'כניסה באמצעות חשבון Google', קודם צריך להפעיל את הספק של 'כניסה באמצעות חשבון Google' בפרויקט Firebase:

  1. במסוף Firebase, פותחים את הקטע Authentication.
  2. בכרטיסייה Sign in method (שיטת כניסה), מפעילים את הספק Google.
  3. לוחצים על שמירה.

  4. מורידים עותק חדש של קובץ GoogleService-Info.plist של הפרויקט ומעתיקים אותו לפרויקט ב-Xcode. מחליפים את כל הגרסאות הקיימות בגרסה החדשה. (מידע נוסף זמין במאמר הוספת Firebase לפרויקט ל-iOS).

ייבוא קובצי הכותרות הנדרשים

קודם כול, צריך לייבא לאפליקציה את קבצי הכותרת של Firebase SDK ושל Google Sign-In SDK.

Swift

import FirebaseCore
import FirebaseAuth
import GoogleSignIn

Objective-C

@import FirebaseCore;
@import GoogleSignIn;

הטמעת כניסה באמצעות חשבון Google

כדי להטמיע את 'כניסה באמצעות חשבון Google', פועלים לפי השלבים הבאים. בתיעוד למפתחים של Google Sign-In מוסבר איך משתמשים ב-Google Sign-In ב-iOS.

  1. מוסיפים לפרויקט Xcode סכמות של כתובות URL בהתאמה אישית:
    1. פותחים את הגדרות הפרויקט: לוחצים על שם הפרויקט בתצוגת העץ שמימין. בוחרים את האפליקציה בקטע TARGETS, ואז בוחרים בכרטיסייה Info ומרחיבים את הקטע URL Types.
    2. לוחצים על הלחצן + ומוסיפים סכימה של כתובת URL למזהה הלקוח ההפוך. כדי למצוא את הערך הזה, פותחים את קובץ התצורה GoogleService-Info.plist ומחפשים את המפתח REVERSED_CLIENT_ID. מעתיקים את הערך של המפתח ומדביקים אותו בתיבה URL Schemes בדף התצורה. משאירים את שאר השדות ללא שינוי.

      בסיום, הקטע של הגדרות ה-config אמור להיראות בערך כך (אבל עם הערכים הספציפיים לאפליקציה שלכם):

  2. ב-method‏ application:didFinishLaunchingWithOptions: של הנציג של האפליקציה, מגדירים את האובייקט FirebaseApp.

    Swift

    FirebaseApp.configure()

    Objective-C

    // Use Firebase library to configure APIs
    [FIRApp configure];
  3. מטמיעים את השיטה application:openURL:options: של הנציג של האפליקציה. השיטה צריכה להפעיל את השיטה handleURL של המופע GIDSignIn, שתטפל כראוי בכתובת ה-URL שהאפליקציה מקבלת בסוף תהליך האימות.

    Swift

    func application(_ app: UIApplication,
                     open url: URL,
                     options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
      return GIDSignIn.sharedInstance.handle(url)
    }

    Objective-C

    - (BOOL)application:(nonnull UIApplication *)application
                openURL:(nonnull NSURL *)url
                options:(nonnull NSDictionary<NSString *, id> *)options {
      return [[GIDSignIn sharedInstance] handleURL:url];
    }
  4. מעבירים את ה-view controller של התצוגה המוצגת ואת מזהה הלקוח של האפליקציה ל-method‏ signIn של ספק הכניסה לחשבון Google, ויוצרים פרטי כניסה לאימות ב-Firebase מהטוקן של אימות Google שנוצר:

    Swift

    guard let clientID = FirebaseApp.app()?.options.clientID else { return }
    
    // Create Google Sign In configuration object.
    let config = GIDConfiguration(clientID: clientID)
    GIDSignIn.sharedInstance.configuration = config
    
    // Start the sign in flow!
    GIDSignIn.sharedInstance.signIn(withPresenting: self) { [unowned self] result, error in
      guard error == nil else {
        // ...
      }
    
      guard let user = result?.user,
        let idToken = user.idToken?.tokenString
      else {
        // ...
      }
    
      let credential = GoogleAuthProvider.credential(withIDToken: idToken,
                                                     accessToken: user.accessToken.tokenString)
    
      // ...
    }

    Objective-C

    GIDConfiguration *config = [[GIDConfiguration alloc] initWithClientID:[FIRApp defaultApp].options.clientID];
    [GIDSignIn.sharedInstance setConfiguration:config];
    
    __weak __auto_type weakSelf = self;
    [GIDSignIn.sharedInstance signInWithPresentingViewController:self
          completion:^(GIDSignInResult * _Nullable result, NSError * _Nullable error) {
      __auto_type strongSelf = weakSelf;
      if (strongSelf == nil) { return; }
    
      if (error == nil) {
        FIRAuthCredential *credential =
        [FIRGoogleAuthProvider credentialWithIDToken:result.user.idToken.tokenString
                                         accessToken:result.user.accessToken.tokenString];
        // ...
      } else {
        // ...
      }
    }];
  5. מוסיפים GIDSignInButton לסטוריבורד, לקובץ XIB או יוצרים אותו באופן פרוגרמטי. כדי להוסיף את הלחצן לסטוריבורד או לקובץ XIB, מוסיפים תצוגה (View) ומגדירים את הכיתה בהתאמה אישית שלה כ-GIDSignInButton.
  6. אופציונלי: אם רוצים להתאים אישית את הלחצן, מבצעים את הפעולות הבאות:

    Swift

    1. ב-view controller, מגדירים את לחצן הכניסה כנכס.
      @IBOutlet weak var signInButton: GIDSignInButton!
    2. מקשרים את הלחצן לנכס signInButton שהצהרתם עליו.
    3. כדי להתאים אישית את הלחצן, מגדירים את המאפיינים של האובייקט GIDSignInButton.

    Objective-C

    1. בקובץ הכותרת של ה-View Controller, מגדירים את לחצן הכניסה כנכס.
      @property(weak, nonatomic) IBOutlet GIDSignInButton *signInButton;
    2. מקשרים את הלחצן לנכס signInButton שהצהרתם עליו.
    3. כדי להתאים אישית את הלחצן, מגדירים את המאפיינים של האובייקט GIDSignInButton.

אימות באמצעות Firebase

לבסוף, משלימים את תהליך ההתחברות ל-Firebase באמצעות פרטי הכניסה שנוצרו בשלב הקודם.

Swift

Auth.auth().signIn(with: credential) { result, error in

  // At this point, our user is signed in
}
    

Objective-C

[[FIRAuth auth] signInWithCredential:credential
                          completion:^(FIRAuthDataResult * _Nullable authResult,
                                       NSError * _Nullable error) {
    if (isMFAEnabled && error && error.code == FIRAuthErrorCodeSecondFactorRequired) {
      FIRMultiFactorResolver *resolver = error.userInfo[FIRAuthErrorUserInfoMultiFactorResolverKey];
      NSMutableString *displayNameString = [NSMutableString string];
      for (FIRMultiFactorInfo *tmpFactorInfo in resolver.hints) {
        [displayNameString appendString:tmpFactorInfo.displayName];
        [displayNameString appendString:@" "];
      }
      [self showTextInputPromptWithMessage:[NSString stringWithFormat:@"Select factor to sign in\n%@", displayNameString]
                           completionBlock:^(BOOL userPressedOK, NSString *_Nullable displayName) {
       FIRPhoneMultiFactorInfo* selectedHint;
       for (FIRMultiFactorInfo *tmpFactorInfo in resolver.hints) {
         if ([displayName isEqualToString:tmpFactorInfo.displayName]) {
           selectedHint = (FIRPhoneMultiFactorInfo *)tmpFactorInfo;
         }
       }
       [FIRPhoneAuthProvider.provider
        verifyPhoneNumberWithMultiFactorInfo:selectedHint
        UIDelegate:nil
        multiFactorSession:resolver.session
        completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) {
          if (error) {
            [self showMessagePrompt:error.localizedDescription];
          } else {
            [self showTextInputPromptWithMessage:[NSString stringWithFormat:@"Verification code for %@", selectedHint.displayName]
                                 completionBlock:^(BOOL userPressedOK, NSString *_Nullable verificationCode) {
             FIRPhoneAuthCredential *credential =
                 [[FIRPhoneAuthProvider provider] credentialWithVerificationID:verificationID
                                                              verificationCode:verificationCode];
             FIRMultiFactorAssertion *assertion = [FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
             [resolver resolveSignInWithAssertion:assertion completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) {
               if (error) {
                 [self showMessagePrompt:error.localizedDescription];
               } else {
                 NSLog(@"Multi factor finanlize sign in succeeded.");
               }
             }];
           }];
          }
        }];
     }];
    }
  else if (error) {
    // ...
    return;
  }
  // User successfully signed in. Get user data from the FIRUser object
  if (authResult == nil) { return; }
  FIRUser *user = authResult.user;
  // ...
}];

השלבים הבאים

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

  • באפליקציות שלכם, אתם יכולים לקבל את פרטי הפרופיל הבסיסיים של המשתמש מהאובייקט User . ניהול משתמשים

  • בכללי האבטחה של Firebase Realtime Database ו-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;
}

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