Catch up on everthing we announced at this year's Firebase Summit. Learn more

Authentifizieren Sie sich mit der Facebook-Anmeldung auf Apple-Plattformen

Sie können Ihren Benutzern erlauben, sich mit ihren Facebook-Konten bei Firebase zu authentifizieren, indem Sie Facebook Login oder Facebook Limited Login in Ihre App integrieren.

Bevor Sie beginnen

Verwenden Sie den Swift Package Manager, um Firebase-Abhängigkeiten zu installieren und zu verwalten.

  1. In Xcode, mit Ihrem App - Projekt zu öffnen, navigieren Sie zu Datei> Swift Packages> Paket hinzufügen Abhängigkeit.
  2. Wenn Sie dazu aufgefordert werden, fügen Sie das SDK-Repository der Firebase Apple Platforms hinzu:
  3.   https://github.com/firebase/firebase-ios-sdk
      
  4. Wählen Sie die Firebase Authentication-Bibliothek aus.
  5. Wenn Sie fertig sind, beginnt Xcode automatisch, Ihre Abhängigkeiten im Hintergrund aufzulösen und herunterzuladen.

Führen Sie als Nächstes einige Konfigurationsschritte aus:

  1. Auf der Facebook für Entwickler - Website, erhält die App - ID und ein App Geheimnis für Ihre App.
  2. Facebook-Anmeldung aktivieren:
    1. In der Firebase Konsole , öffnen Sie den Abschnitt Auth.
    2. Auf dem Anmelden Methode Registerkarte, aktivieren Sie die Facebook-Anmeldeverfahren und geben Sie die App - ID und App Geheimnis Sie von Facebook bekommen.
    3. Dann stellen Sie sicher , dass Ihr OAuth Umleitung URI (zB my-app-12345.firebaseapp.com/__/auth/handler ) als eine Ihrer OAuth Umleitung URIs in Ihrer Facebook - App - Einstellungen Seite auf der aufgeführt ist Facebook für Entwickler - Website im Produkt Einstellungen> Facebook Login - Konfiguration.

Implementieren Sie die Facebook-Anmeldung

Um die "klassische" Facebook-Anmeldung zu verwenden, führen Sie die folgenden Schritte aus. Alternativ können Sie Facebook Limited Login verwenden, wie im nächsten Abschnitt gezeigt.

  1. Integrieren Facebook Login in Ihre App durch die folgende Dokumentation des Entwicklers . Wenn Sie das initialisieren FBSDKLoginButton Objekt, setzen Sie einen Delegaten Login- und Logout - Ereignisse zu empfangen. Zum Beispiel:

    Schnell

    let loginButton = FBSDKLoginButton()
    loginButton.delegate = self
    

    Ziel c

    FBSDKLoginButton *loginButton = [[FBSDKLoginButton alloc] init];
    loginButton.delegate = self;
    
    In Ihrem Delegierten implementieren didCompleteWithResult:error: .

    Schnell

    func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
      if let error = error {
        print(error.localizedDescription)
        return
      }
      // ...
    }
    

    Ziel c

    - (void)loginButton:(FBSDKLoginButton *)loginButton
        didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result
                        error:(NSError *)error {
      if (error == nil) {
        // ...
      } else {
        NSLog(error.localizedDescription);
      }
    }
    
  2. Importieren Sie die Firebase Modul in Ihrem UIApplicationDelegate :

    Schnell

    import Firebase

    Ziel c

    @import Firebase;
  3. Konfigurieren ein FirebaseApp gemeinsame Instanz, in der Regel in Ihrem App - application:didFinishLaunchingWithOptions: Methode:

    Schnell

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

    Ziel c

    // Use Firebase library to configure APIs
    [FIRApp configure];
  4. Nachdem ein Benutzer erfolgreich anmeldet, in der Implementierung von didCompleteWithResult:error: eine Zugriffs - Token für die angemeldeten Nutzer und tauschen sie für eine Firebase Berechtigungsnachweis:

    Schnell

    let credential = FacebookAuthProvider
      .credential(withAccessToken: AccessToken.current!.tokenString)
    

    Ziel c

    FIRAuthCredential *credential = [FIRFacebookAuthProvider
        credentialWithAccessToken:[FBSDKAccessToken currentAccessToken].tokenString];
    

Implementieren Sie Facebook Limited Login

Um Facebook Limited Login anstelle des "klassischen" Facebook Logins zu verwenden, führen Sie die folgenden Schritte aus.

  1. Integrieren Facebook Begrenzte Einloggen in Ihre Anwendung durch die folgende Dokumentation des Entwicklers .
  2. Generieren Sie für jede Anmeldeanfrage eine eindeutige zufällige Zeichenfolge – eine „Nonce“ –, die Sie verwenden werden, um sicherzustellen, dass das ID-Token, das Sie erhalten, speziell als Antwort auf die Authentifizierungsanfrage Ihrer App gewährt wurde. Dieser Schritt ist wichtig, um Replay-Angriffe zu verhindern. Sie können eine kryptografisch sicheren nonce mit generieren SecRandomCopyBytes(_:_:_) , wie im folgenden Beispiel:

    Schnell

    // Adapted from https://auth0.com/docs/api-auth/tutorials/nonce#generate-a-cryptographically-random-nonce
    private func randomNonceString(length: Int = 32) -> String {
      precondition(length > 0)
      let charset: [Character] =
        Array("0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._")
      var result = ""
      var remainingLength = length
    
      while remainingLength > 0 {
        let randoms: [UInt8] = (0 ..< 16).map { _ in
          var random: UInt8 = 0
          let errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random)
          if errorCode != errSecSuccess {
            fatalError(
              "Unable to generate nonce. SecRandomCopyBytes failed with OSStatus \(errorCode)"
            )
          }
          return random
        }
    
        randoms.forEach { random in
          if remainingLength == 0 {
            return
          }
    
          if random < charset.count {
            result.append(charset[Int(random)])
            remainingLength -= 1
          }
        }
      }
    
      return result
    }
    
            

    Ziel c

    // Adapted from https://auth0.com/docs/api-auth/tutorials/nonce#generate-a-cryptographically-random-nonce
    - (NSString *)randomNonce:(NSInteger)length {
      NSAssert(length > 0, @"Expected nonce to have positive length");
      NSString *characterSet = @"0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._";
      NSMutableString *result = [NSMutableString string];
      NSInteger remainingLength = length;
    
      while (remainingLength > 0) {
        NSMutableArray *randoms = [NSMutableArray arrayWithCapacity:16];
        for (NSInteger i = 0; i < 16; i++) {
          uint8_t random = 0;
          int errorCode = SecRandomCopyBytes(kSecRandomDefault, 1, &random);
          NSAssert(errorCode == errSecSuccess, @"Unable to generate nonce: OSStatus %i", errorCode);
    
          [randoms addObject:@(random)];
        }
    
        for (NSNumber *random in randoms) {
          if (remainingLength == 0) {
            break;
          }
    
          if (random.unsignedIntValue < characterSet.length) {
            unichar character = [characterSet characterAtIndex:random.unsignedIntValue];
            [result appendFormat:@"%C", character];
            remainingLength--;
          }
        }
      }
    
      return [result copy];
    }
            
    Sie senden mit Ihrer Anmeldeanfrage den SHA-256-Hash der Nonce, den Facebook unverändert in der Antwort übergibt. Firebase validiert die Antwort durch Hashing der ursprünglichen Nonce und vergleicht sie mit dem von Facebook übergebenen Wert.

    Schnell

    @available(iOS 13, *)
    private func sha256(_ input: String) -> String {
      let inputData = Data(input.utf8)
      let hashedData = SHA256.hash(data: inputData)
      let hashString = hashedData.compactMap {
        String(format: "%02x", $0)
      }.joined()
    
      return hashString
    }
    
            

    Ziel c

    - (NSString *)stringBySha256HashingString:(NSString *)input {
      const char *string = [input UTF8String];
      unsigned char result[CC_SHA256_DIGEST_LENGTH];
      CC_SHA256(string, (CC_LONG)strlen(string), result);
    
      NSMutableString *hashed = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
      for (NSInteger i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
        [hashed appendFormat:@"%02x", result[i]];
      }
      return hashed;
    }
            
  3. Wenn Sie das einrichten FBSDKLoginButton , setzen Sie einen Delegaten Login- und Logout - Ereignisse zu erhalten, die Tracking - Modus einzustellen FBSDKLoginTrackingLimited und eine Nonce zu befestigen. Zum Beispiel:

    Schnell

    func setupLoginButton() {
        let nonce = randomNonceString()
        currentNonce = nonce
        loginButton.delegate = self
        loginButton.loginTracking = .limited
        loginButton.nonce = sha256(nonce)
    }
            

    Ziel c

    - (void)setupLoginButton {
      NSString *nonce = [self randomNonce:32];
      self.currentNonce = nonce;
      self.loginButton.delegate = self;
      self.loginButton.loginTracking = FBSDKLoginTrackingLimited
      self.loginButton.nonce = [self stringBySha256HashingString:nonce];
    }
            
    In Ihrem Delegierten implementieren didCompleteWithResult:error: .

    Schnell

    func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) {
      if let error = error {
        print(error.localizedDescription)
        return
      }
      // ...
    }
            

    Ziel c

    - (void)loginButton:(FBSDKLoginButton *)loginButton
        didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result
                        error:(NSError *)error {
      if (error == nil) {
        // ...
      } else {
        NSLog(error.localizedDescription);
      }
    }
            
  4. Importieren Sie die Firebase Modul in Ihrem UIApplicationDelegate :

    Schnell

    import Firebase

    Ziel c

    @import Firebase;
  5. Konfigurieren ein FirebaseApp gemeinsame Instanz, in der Regel in Ihrem App - application:didFinishLaunchingWithOptions: Methode:

    Schnell

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

    Ziel c

    // Use Firebase library to configure APIs
    [FIRApp configure];
  6. Nachdem ein Benutzer erfolgreich anmeldet, in der Implementierung von didCompleteWithResult:error: die ID verwenden , um von Facebook-Antwort mit dem ungehashte nonce Token eine Firebase Berechtigungsnachweis zu erhalten:

    Schnell

    // Initialize a Firebase credential.
    let idTokenString = AuthenticationToken.current?.tokenString
    let nonce = currentNonce
    let credential = OAuthProvider.credential(withProviderID: "facebook.com",
                                              idToken: idTokenString!,
                                              rawNonce: nonce)
            

    Ziel c

    // Initialize a Firebase credential.
    NSString *idTokenString = FBSDKAuthenticationToken.currentAuthenticationToken.tokenString;
    NSString *rawNonce = self.currentNonce;
    FIROAuthCredential *credential = [FIROAuthProvider credentialWithProviderID:@"facebook.com"
                                                                        IDToken:idTokenString
                                                                       rawNonce:rawNonce];
            

Mit Firebase authentifizieren

Zum Schluss authentifizieren Sie sich bei Firebase mit den Firebase-Anmeldeinformationen:

Schnell

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
    // ...
}
    

Ziel 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;
  // ...
}];
    

Nächste Schritte

Nachdem sich ein Benutzer zum ersten Mal anmeldet, wird ein neues Benutzerkonto erstellt und mit den Anmeldeinformationen – d. h. Benutzername und Kennwort, Telefonnummer oder Authentifizierungsanbieterinformationen – verknüpft, mit denen sich der Benutzer angemeldet hat. Dieses neue Konto wird als Teil Ihres Firebase-Projekts gespeichert und kann verwendet werden, um einen Benutzer in jeder App in Ihrem Projekt zu identifizieren, unabhängig davon, wie sich der Benutzer anmeldet.

  • In Ihren Anwendungen können Sie die Benutzerprofilgrundinformationen aus dem bekommen FIRUser Objekt. Siehe Benutzer verwalten .

  • In Ihrer Datenbank und Firebase Realtime Cloud Storage Sicherheitsregeln , können Sie die angemeldeten Nutzer die eindeutige Benutzer - ID aus der bekommen auth Variable, und es verwenden , um steuern kann ein Benutzer Zugriff , welche Daten.

Sie können Benutzer erlauben , durch mehrere Authentifizierungsanbieter anmelden, um Ihre App Verknüpfung Auth - Provider - Anmeldeinformationen zu einem vorhandenen Benutzerkonto.

Um einen Benutzer abzumelden, rufen signOut: .

Schnell

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

Ziel c

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

Möglicherweise möchten Sie auch einen Fehlerbehandlungscode für alle Authentifizierungsfehler hinzufügen. Siehe Handle Fehler .