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

Apple Platformlarında Bir Hesaba Birden Çok Kimlik Doğrulama Sağlayıcısı Bağlayın

Kimlik doğrulama sağlayıcısı kimlik bilgilerini mevcut bir kullanıcı hesabına bağlayarak, kullanıcıların birden çok kimlik doğrulama sağlayıcısı kullanarak uygulamanızda oturum açmasına izin verebilirsiniz. Kullanıcılar, oturum açmak için kullandıkları kimlik doğrulama sağlayıcısından bağımsız olarak aynı Firebase kullanıcı kimliğiyle tanımlanabilir. Örneğin, bir şifre ile oturum açan bir kullanıcı, gelecekte bir Google hesabını bağlayabilir ve herhangi bir yöntemle oturum açabilir. Veya anonim bir kullanıcı bir Facebook hesabını bağlayabilir ve ardından uygulamanızı kullanmaya devam etmek için Facebook ile oturum açabilir.

Sen başlamadan önce

Uygulamanıza iki veya daha fazla kimlik doğrulama sağlayıcısı (muhtemelen anonim kimlik doğrulama dahil) için destek ekleyin.

Yetkilendirme sağlayıcı kimlik bilgilerini mevcut bir kullanıcı hesabına bağlamak için:

  1. Herhangi bir kimlik doğrulama sağlayıcısı veya yöntemi kullanarak kullanıcıda oturum açın.
  2. Yeni kimlik doğrulama sağlayıcısı kadar tabelasını açma akışı tamamlayın, ancak birini çağırarak, dahil değil FIRAuth.signInWith yöntemlerle. Örneğin, kullanıcının Google ID jetonunu, Facebook erişim jetonunu veya e-posta ve şifresini alın.
  3. Bir alın FIRAuthCredential yeni kimlik doğrulama sağlayıcısı için:

    Google Oturum Açma
    Süratli
    guard
      let authentication = user?.authentication,
      let idToken = authentication.idToken
    else {
      return
    }
    
    let credential = GoogleAuthProvider.credential(withIDToken: idToken,
                                                   accessToken: authentication.accessToken)
    
    Amaç-C
    GIDAuthentication *authentication = user.authentication;
    FIRAuthCredential *credential =
    [FIRGoogleAuthProvider credentialWithIDToken:authentication.idToken
                                     accessToken:authentication.accessToken];
    
    Facebook Girişi
    Süratli
    let credential = FacebookAuthProvider
      .credential(withAccessToken: AccessToken.current!.tokenString)
    
    Amaç-C
    FIRAuthCredential *credential = [FIRFacebookAuthProvider
        credentialWithAccessToken:[FBSDKAccessToken currentAccessToken].tokenString];
    
    E-posta-şifre oturum açma
    Süratli
    let credential = EmailAuthProvider.credential(withEmail: email, password: password)
    
    Amaç-C
    FIRAuthCredential *credential =
        [FIREmailAuthProvider credentialWithEmail:email
                                                 password:password];
    
  4. Geçiş FIRAuthCredential imza-kullanıcının nesneyi linkWithCredential:completion: yöntemi:

    Süratli
        user.link(with: credential) { authResult, error in
      // ...
    }
    }
    
    Amaç-C
        [[FIRAuth auth].currentUser linkWithCredential:credential
        completion:^(FIRAuthDataResult *result, NSError *_Nullable error) {
      // ...
    }];
    

    Çağrısı linkWithCredential:completion: kimlik bilgileri zaten başka bir kullanıcı hesabına bağlı olup olmadığını başarısız olur. Bu durumda, uygulamanız için uygun şekilde hesapları ve ilişkili verileri birleştirmeyi ele almalısınız:

    Süratli

    let prevUser = Auth.auth().currentUser
    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
        // ...
    }
                // Merge prevUser and currentUser accounts and data
                // ...
            }
    

    Amaç-C

    FIRUser *prevUser = [FIRAuth auth].currentUser;
    [[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;
      // ...
    }];
                                        // Merge prevUser and currentUser accounts and data
                                        // ...
                                    }];
    

Çağrısı Eğer linkWithCredential:completion: başarır, kullanıcı artık herhangi bir bağlı kimlik doğrulama sağlayıcı ve erişim aynı Firebase verilerini kullanarak oturum açabilirsiniz.

Bir kimlik doğrulama sağlayıcısının bir hesapla bağlantısını kaldırabilirsiniz, böylece kullanıcı artık o sağlayıcıyla oturum açamaz.

Bir kullanıcı hesabından yetkilendirme sağlayıcı bağlantısını kaldırmak için sağlayıcı numarası geçmesi unlinkFromProvider:completion: yöntem. Sen bir kullanıcıya bağlı yetkilendirme sağlayıcılarının sağlayıcı kimliklerini alabilirsiniz providerData özelliği.

Süratli

Auth.auth().currentUser?.unlink(fromProvider: providerID!) { user, error in
  // ...
}

Amaç-C

[[FIRAuth auth].currentUser unlinkFromProvider:providerID
                                    completion:^(FIRUser *_Nullable user, NSError *_Nullable error) {
  // ...
}];