Google is committed to advancing racial equity for Black communities. See how.
דף זה תורגם על ידי Cloud Translation API.
Switch to English

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

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

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

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

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

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

מָהִיר

בנציג האפליקציה שלך, ייבא את קבצי הכותרת הבאים:

import Firebase
import GoogleSignIn

בבקר התצוגה של תצוגת הכניסה שלך, ייבא את קבצי הכותרת הבאים:

import Firebase
import GoogleSignIn

מטרה-ג

בנציג האפליקציה שלך, ייבא את קבצי הכותרת הבאים:

@import Firebase;
@import GoogleSignIn;

בבקר התצוגה של תצוגת הכניסה שלך, ייבא את קבצי הכותרת הבאים:

@import Firebase;
@import GoogleSignIn;

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

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

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

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

  2. הצהיר כי נציג האפליקציות מיישם את פרוטוקול GIDSignInDelegate .

    מָהִיר

    ב- AppDelegate.swift :
    class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {
    

    מטרה-ג

    ב- AppDelegate.h :
    @interface AppDelegate : UIResponder<UIApplicationDelegate, GIDSignInDelegate>
    
  3. ביישום נציג application:didFinishLaunchingWithOptions: שיטת application:didFinishLaunchingWithOptions: הגדר את האובייקט FirebaseApp והגדר את נציג הכניסה.

    מָהִיר

    // Use Firebase library to configure APIs
    FirebaseApp.configure()
    
    GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID
    GIDSignIn.sharedInstance().delegate = self
    

    מטרה-ג

    // Use Firebase library to configure APIs
    [FIRApp configure];
    
    [GIDSignIn sharedInstance].clientID = [FIRApp defaultApp].options.clientID;
    [GIDSignIn sharedInstance].delegate = self;
    
  4. יישם את application:openURL:options: שיטת נציג האפליקציה שלך. על השיטה לקרוא לשיטת 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];
    }
    

    כדי שהאפליקציה שלך תפעל ב- iOS 8 ומעלה, יישם גם את application:openURL:sourceApplication:annotation: שהוצא משימוש application:openURL:sourceApplication:annotation: method.

    מָהִיר

    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
        return GIDSignIn.sharedInstance().handle(url)
    }
    

    מטרה-ג

    - (BOOL)application:(UIApplication *)application
                openURL:(NSURL *)url
      sourceApplication:(NSString *)sourceApplication
             annotation:(id)annotation {
      return [[GIDSignIn sharedInstance] handleURL:url];
    }
    
  5. GIDSignInDelegate האפליקציה, GIDSignInDelegate את פרוטוקול GIDSignInDelegate לטיפול בתהליך הכניסה על ידי הגדרת השיטות הבאות:

    מטרה-ג

    - (void)signIn:(GIDSignIn *)signIn
    didSignInForUser:(GIDGoogleUser *)user
         withError:(NSError *)error {
      // ...
      if (error == nil) {
        GIDAuthentication *authentication = user.authentication;
        FIRAuthCredential *credential =
        [FIRGoogleAuthProvider credentialWithIDToken:authentication.idToken
                                         accessToken:authentication.accessToken];
        // ...
      } else {
        // ...
      }
    }
    
    - (void)signIn:(GIDSignIn *)signIn
    didDisconnectWithUser:(GIDGoogleUser *)user
         withError:(NSError *)error {
      // Perform any operations when the user disconnects from app here.
      // ...
    }
    

    מָהִיר

    func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) {
      // ...
      if let error = error {
        // ...
        return
      }
    
      guard let authentication = user.authentication else { return }
      let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken,
                                                        accessToken: authentication.accessToken)
      // ...
    }
    
    func sign(_ signIn: GIDSignIn!, didDisconnectWith user: GIDGoogleUser!, withError error: Error!) {
        // Perform any operations when the user disconnects from app here.
        // ...
    }
    
  6. בבקר התצוגה, viewDidLoad את שיטת viewDidLoad כדי להגדיר את בקר התצוגה המציג של אובייקט GIDSignIn , ו (אופציונלי) להיכנס בשקט במידת האפשר.

    מטרה-ג

    [GIDSignIn sharedInstance].presentingViewController = self;
    [[GIDSignIn sharedInstance] signIn];
    

    מָהִיר

    GIDSignIn.sharedInstance()?.presentingViewController = self
    GIDSignIn.sharedInstance().signIn()
    
  7. הוסף GIDSignInButton ללוח התכנון, לקובץ ה- XIB שלך, או התאם אותו באופן תכנותי. כדי להוסיף את הלחצן ללוח התכנון או לקובץ ה- XIB שלך, הוסף תצוגה והגדר את המחלקה המותאמת אישית שלו ל- GIDSignInButton .
  8. אופציונלי : אם ברצונך להתאים אישית את הכפתור, בצע את הפעולות הבאות:

    מָהִיר

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

    מטרה-ג

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

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

ב- signIn:didSignInForUser:withError: מתודה, קבל אסימון מזהה Google ואסימון גישה של GIDAuthentication מאובייקט GIDAuthentication תמורת אישורי Firebase:

מָהִיר

func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error?) {
  // ...
  if let error = error {
    // ...
    return
  }

  guard let authentication = user.authentication else { return }
  let credential = GoogleAuthProvider.credential(withIDToken: authentication.idToken,
                                                    accessToken: authentication.accessToken)
  // ...
}

מטרה-ג

- (void)signIn:(GIDSignIn *)signIn
didSignInForUser:(GIDGoogleUser *)user
     withError:(NSError *)error {
  // ...
  if (error == nil) {
    GIDAuthentication *authentication = user.authentication;
    FIRAuthCredential *credential =
    [FIRGoogleAuthProvider credentialWithIDToken:authentication.idToken
                                     accessToken:authentication.accessToken];
    // ...
  } else {
    // ...
  }
}

לבסוף, אמת באמצעות 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;
}

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