אמת באמצעות כניסה של Google ב- iOS

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

לפני שאתה מתחיל

  1. להוסיף Firebase לפרויקט iOS שלך . כלול את התרמילים הבאים שלך Podfile :
    pod 'Firebase/Auth'
    pod 'GoogleSignIn'
    
  2. אם עדיין לא מחוברת האפליקציה שלך לפרויקט Firebase שלך, לעשות זאת מתוך קונסולת Firebase .
  3. הפעל כניסה של Google במסוף Firebase:
    1. בשנות ה קונסולת Firebase , פתח את הקטע המחבר.
    2. 'הכניסה דרך כרטיסיית שיטה, לאפשר כניסת גוגל שיטה ולחץ על שמור.

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

ראשית, עליך לייבא את קבצי כותרת ה- SDK של Firebase ו- Google כניסה SDK לאפליקציה שלך.

מָהִיר

import Firebase
import GoogleSignIn

מטרה-ג

@import Firebase;
@import GoogleSignIn;

2. יישם כניסה של Google

יישום הכניסה של Google על ידי ביצוע השלבים הבאים. עיין כניסה עם גוגל תיעוד המפתח לקבלת פרטים אודות השימוש גוגל להיכנס עם iOS.

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

      בסיום התצורה שלך צריכה להיראות דומה לדברים הבאים (אך עם הערכים הספציפיים ליישום שלך):

  2. בשינה של delegate של יישום application:didFinishLaunchingWithOptions: שיטה, להגדיר את FirebaseApp האובייקט.

    מָהִיר

    // Use Firebase library to configure APIs
    FirebaseApp.configure()
    

    מטרה-ג

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

    מָהִיר

    @available(iOS 9.0, *)
    func application(_ application: UIApplication, open url: URL,
                     options: [UIApplication.OpenURLOptionsKey: Any])
      -> Bool {
      return GIDSignIn.sharedInstance.handle(url)
    }
    

    מטרה-ג

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

    מָהִיר

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

    מטרה-ג

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

    מָהִיר

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

    מטרה-ג

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

3. אמת עם Firebase

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

מָהִיר

Auth.auth().signIn(with: credential) { authResult, error in
    if let error = error {
      let authError = error as NSError
      if isMFAEnabled, authError.code == AuthErrorCode.secondFactorRequired.rawValue {
        // The user is a multi-factor user. Second factor challenge is required.
        let resolver = authError
          .userInfo[AuthErrorUserInfoMultiFactorResolverKey] as! MultiFactorResolver
        var displayNameString = ""
        for tmpFactorInfo in resolver.hints {
          displayNameString += tmpFactorInfo.displayName ?? ""
          displayNameString += " "
        }
        self.showTextInputPrompt(
          withMessage: "Select factor to sign in\n\(displayNameString)",
          completionBlock: { userPressedOK, displayName in
            var selectedHint: PhoneMultiFactorInfo?
            for tmpFactorInfo in resolver.hints {
              if displayName == tmpFactorInfo.displayName {
                selectedHint = tmpFactorInfo as? PhoneMultiFactorInfo
              }
            }
            PhoneAuthProvider.provider()
              .verifyPhoneNumber(with: selectedHint!, uiDelegate: nil,
                                 multiFactorSession: resolver
                                   .session) { verificationID, error in
                if error != nil {
                  print(
                    "Multi factor start sign in failed. Error: \(error.debugDescription)"
                  )
                } else {
                  self.showTextInputPrompt(
                    withMessage: "Verification code for \(selectedHint?.displayName ?? "")",
                    completionBlock: { userPressedOK, verificationCode in
                      let credential: PhoneAuthCredential? = PhoneAuthProvider.provider()
                        .credential(withVerificationID: verificationID!,
                                    verificationCode: verificationCode!)
                      let assertion: MultiFactorAssertion? = PhoneMultiFactorGenerator
                        .assertion(with: credential!)
                      resolver.resolveSignIn(with: assertion!) { authResult, error in
                        if error != nil {
                          print(
                            "Multi factor finanlize sign in failed. Error: \(error.debugDescription)"
                          )
                        } else {
                          self.navigationController?.popViewController(animated: true)
                        }
                      }
                    }
                  )
                }
              }
          }
        )
      } else {
        self.showMessagePrompt(error.localizedDescription)
        return
      }
      // ...
      return
    }
    // User is signed in
    // ...
}

מטרה-ג

[[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 שלך, וניתן להשתמש בו כדי לזהות משתמש בכל אפליקציה בפרויקט שלך, ללא קשר לאופן בו המשתמש נכנס.

  • באפליקציות שלך, אתה יכול לקבל את המידע הבסיסי של הפרופיל האישי של המשתמש מן FIRUser האובייקט. ראו ניהול משתמשים .

  • בבסיס הנתונים בזמן אמת Firebase שלך לאחסון בענן אבטחה חוקי , אתה יכול לקבל את שנכנסים למערכת זיהוי המשתמש הייחודי של המשתמש מן auth משתנה, ולהשתמש בו כדי לקבוע אילו נתונים גישה יכול משתמש.

תוכל לאפשר למשתמשים להיכנס לאפליקציה שלך דרך ספקי אימות מרובים על ידי מקשר auth אישורי ספק לחשבון משתמש קיים.

כדי לצאת מהחשבון משתמש, קוראים signOut: .

מָהִיר

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

מטרה-ג

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

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