Vous pouvez autoriser les utilisateurs à se connecter à votre application à l'aide de plusieurs fournisseurs d'authentification en liant les informations d'identification du fournisseur d'authentification à un compte d'utilisateur existant. Les utilisateurs sont identifiables par le même ID utilisateur Firebase, quel que soit le fournisseur d'authentification utilisé pour se connecter. Par exemple, un utilisateur qui s'est connecté avec un mot de passe peut lier un compte Google et se connecter avec l'une ou l'autre méthode à l'avenir. Ou, un utilisateur anonyme peut lier un compte Facebook puis, plus tard, se connecter avec Facebook pour continuer à utiliser votre application.
Avant que tu commences
Ajoutez la prise en charge de deux fournisseurs d'authentification ou plus (y compris éventuellement l'authentification anonyme) à votre application.
Lier les informations d'identification du fournisseur d'authentification à un compte d'utilisateur
Pour lier les informations d'identification du fournisseur d'authentification à un compte utilisateur existant :
- Connectez l'utilisateur à l'aide de n'importe quel fournisseur ou méthode d'authentification.
- Terminez le flux de connexion pour le nouveau fournisseur d'authentification jusqu'à l'appel de l'une des méthodes
FIRAuth.signInWith
. Par exemple, obtenez le jeton d'identification Google de l'utilisateur, le jeton d'accès Facebook ou l'e-mail et le mot de passe. Obtenez un
FIRAuthCredential
pour le nouveau fournisseur d'authentification :Connexion Google
Rapide
guard let authentication = user?.authentication, let idToken = authentication.idToken else { return } let credential = GoogleAuthProvider.credential(withIDToken: idToken, accessToken: authentication.accessToken)
Objectif c
FIRAuthCredential *credential = [FIRGoogleAuthProvider credentialWithIDToken:result.user.idToken.tokenString accessToken:result.user.accessToken.tokenString];
Identifiant Facebook
Rapide
let credential = FacebookAuthProvider .credential(withAccessToken: AccessToken.current!.tokenString)
Objectif c
FIRAuthCredential *credential = [FIRFacebookAuthProvider credentialWithAccessToken:[FBSDKAccessToken currentAccessToken].tokenString];
Connexion par e-mail et mot de passe
Rapide
let credential = EmailAuthProvider.credential(withEmail: email, password: password)
Objectif c
FIRAuthCredential *credential = [FIREmailAuthProvider credentialWithEmail:email password:password];
Transmettez l'objet
FIRAuthCredential
à la méthodelinkWithCredential:completion:
de l'utilisateur connecté :Rapide
user.link(with: credential) { authResult, error in // ... } }
Objectif c
[[FIRAuth auth].currentUser linkWithCredential:credential completion:^(FIRAuthDataResult *result, NSError *_Nullable error) { // ... }];
L'appel à
linkWithCredential:completion:
échouera si les identifiants sont déjà liés à un autre compte utilisateur. Dans ce cas, vous devez gérer la fusion des comptes et des données associées en fonction de votre application :Rapide
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 // ... }
Objectif 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 // ... }];
Si l'appel à linkWithCredential:completion:
réussit, l'utilisateur peut désormais se connecter à l'aide de n'importe quel fournisseur d'authentification lié et accéder aux mêmes données Firebase.
Dissocier un fournisseur d'authentification d'un compte utilisateur
Vous pouvez dissocier un fournisseur d'authentification d'un compte, afin que l'utilisateur ne puisse plus se connecter avec ce fournisseur.
Pour dissocier un fournisseur d'authentification d'un compte utilisateur, transmettez l'ID du fournisseur à la méthode unlink
. Vous pouvez obtenir les ID de fournisseur des fournisseurs d'authentification liés à un utilisateur à partir de la propriété providerData
.
Rapide
Auth.auth().currentUser?.unlink(fromProvider: providerID!) { user, error in // ... }
Objectif c
[[FIRAuth auth].currentUser unlinkFromProvider:providerID completion:^(FIRUser *_Nullable user, NSError *_Nullable error) { // ... }];