Si vous avez effectué la mise à niveau vers Firebase Authentication with Identity Platform, vous pouvez ajouter l'authentification multifacteur SMS à votre application iOS.
L'authentification multifacteur augmente la sécurité de votre application. Alors que les attaquants compromettent souvent les mots de passe et les comptes sociaux, l'interception d'un message texte est plus difficile.
Avant que tu commences
Activez au moins un fournisseur prenant en charge l'authentification multifacteur. Chaque fournisseur prend en charge MFA, à l' exception de l'authentification par téléphone, de l'authentification anonyme et d'Apple Game Center.
Assurez-vous que votre application vérifie les e-mails des utilisateurs. MFA nécessite une vérification par e-mail. Cela empêche les acteurs malveillants de s'inscrire à un service avec un e-mail qu'ils ne possèdent pas, puis de verrouiller le véritable propriétaire en ajoutant un deuxième facteur.
Activer l'authentification multifacteur
Ouvrez la page Authentification > Méthode de connexion de la console Firebase.
Dans la section Avancé , activez Authentification multifacteur SMS .
Vous devez également entrer les numéros de téléphone avec lesquels vous testerez votre application. Bien que facultatif, l'enregistrement des numéros de téléphone de test est fortement recommandé pour éviter les limitations pendant le développement.
Si vous n'avez pas encore autorisé le domaine de votre application, ajoutez-le à la liste verte sur la page Authentification > Paramètres de la console Firebase.
Vérification de votre application
Firebase doit vérifier que les requêtes SMS proviennent de votre application. Vous pouvez le faire de deux manières :
Notifications APN silencieuses : lorsque vous connectez un utilisateur pour la première fois, Firebase peut envoyer une notification push silencieuse à l'appareil de l'utilisateur. L'authentification peut continuer si l'application reçoit la notification. Notez qu'à partir d'iOS 8.0, vous n'avez pas besoin de demander à l'utilisateur d'autoriser les notifications push pour utiliser cette méthode.
Vérification reCAPTCHA : si vous ne pouvez pas envoyer de notification silencieuse (par exemple, parce que l'utilisateur a désactivé l'actualisation en arrière-plan ou que vous testez votre application dans le simulateur iOS), vous pouvez utiliser reCAPTCHA. Dans de nombreux cas, le reCAPTCHA se résoudra automatiquement sans interaction de l'utilisateur.
Utilisation des notifications silencieuses
Pour activer les notifications APN à utiliser avec Firebase :
Dans Xcode, activez les notifications push pour votre projet.
Téléchargez votre clé d'authentification APNs à l'aide de la console Firebase (vos modifications seront automatiquement répercutées sur Google Cloud Firebase). Si vous n'avez pas encore votre clé d'authentification APNs, consultez Configuration des APNs avec FCM pour savoir comment l'obtenir.
Ouvrez la console Firebase .
Accédez aux paramètres du projet .
Sélectionnez l'onglet Messagerie Cloud .
Sous Clé d' authentification APNs , dans la section de configuration de l'application iOS , cliquez sur Charger .
Sélectionnez votre clé.
Ajoutez l'ID de clé pour la clé. Vous pouvez trouver l'ID de clé sous Certificats, identifiants et profils dans l' Apple Developer Member Center .
Cliquez sur Télécharger .
Si vous avez déjà un certificat APNs, vous pouvez le télécharger à la place.
Utilisation de la vérification reCAPTCHA
Pour permettre au SDK client d'utiliser reCAPTCHA :
Ouvrez la configuration de votre projet dans Xcode.
Double-cliquez sur le nom du projet dans l'arborescence de gauche.
Sélectionnez votre application dans la section Cibles .
Sélectionnez l'onglet Infos .
Développez la section Types d'URL .
Cliquez sur le bouton + .
Saisissez votre ID client inversé dans le champ Schémas d'URL . Vous pouvez trouver cette valeur répertoriée dans le fichier de configuration
GoogleService-Info.plist
sous la formeREVERSED_CLIENT_ID
.
Une fois terminée, votre configuration devrait ressembler à ce qui suit :
En option, vous pouvez personnaliser la façon dont votre application présente le SFSafariViewController
ou UIWebView
lors de l'affichage du reCAPTCHA. Pour ce faire, créez une classe personnalisée conforme au protocole FIRAuthUIDelegate
et transmettez-la à verifyPhoneNumber:UIDelegate:completion:
.
Choisir un modèle d'inscription
Vous pouvez choisir si votre application requiert une authentification multifacteur, et comment et quand inscrire vos utilisateurs. Certains modèles courants incluent :
Inscrivez le deuxième facteur de l'utilisateur dans le cadre de l'inscription. Utilisez cette méthode si votre application nécessite une authentification multifacteur pour tous les utilisateurs. Notez qu'un compte doit avoir une adresse e-mail vérifiée pour inscrire un deuxième facteur, votre processus d'inscription devra donc en tenir compte.
Offrez une option désactivable pour inscrire un deuxième facteur lors de l'inscription. Les applications qui souhaitent encourager, mais pas exiger, l'authentification multifacteur peuvent préférer cette approche.
Offrez la possibilité d'ajouter un deuxième facteur à partir de la page de gestion du compte ou du profil de l'utilisateur, au lieu de l'écran d'inscription. Cela minimise les frictions pendant le processus d'inscription, tout en rendant l'authentification multifacteur disponible pour les utilisateurs sensibles à la sécurité.
Nécessite l'ajout progressif d'un deuxième facteur lorsque l'utilisateur souhaite accéder à des fonctionnalités avec des exigences de sécurité accrues.
Inscrire un deuxième facteur
Pour inscrire un nouveau facteur secondaire pour un utilisateur :
Réauthentifiez l'utilisateur.
Demandez à l'utilisateur d'entrer son numéro de téléphone.
Obtenez une session multi-facteurs pour l'utilisateur :
Rapide
authResult.user.multiFactor.getSessionWithCompletion() { (session, error) in // ... }
Objectif c
[authResult.user.multiFactor getSessionWithCompletion:^(FIRMultiFactorSession * _Nullable session, NSError * _Nullable error) { // ... }];
Envoyez un message de vérification au téléphone de l'utilisateur. Assurez-vous que le numéro de téléphone est formaté avec un signe
+
et aucun autre signe de ponctuation ou espace blanc (par exemple :+15105551234
)Rapide
// Send SMS verification code. PhoneAuthProvider.provider().verifyPhoneNumber( phoneNumber, uiDelegate: nil, multiFactorSession: session) { (verificationId, error) in // verificationId will be needed for enrollment completion. }
Objectif c
// Send SMS verification code. [FIRPhoneAuthProvider.provider verifyPhoneNumber:phoneNumber UIDelegate:nil multiFactorSession:session completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) { // verificationId will be needed for enrollment completion. }];
Bien que cela ne soit pas obligatoire, il est recommandé d'informer les utilisateurs à l'avance qu'ils recevront un SMS et que les tarifs standard s'appliquent.
La méthode
verifyPhoneNumber()
démarre le processus de vérification de l'application en arrière-plan à l'aide d'une notification push silencieuse. Si la notification push silencieuse n'est pas disponible, un défi reCAPTCHA est émis à la place.Une fois le code SMS envoyé, demandez à l'utilisateur de vérifier le code. Ensuite, utilisez leur réponse pour créer un
PhoneAuthCredential
:Rapide
// Ask user for the verification code. Then: let credential = PhoneAuthProvider.provider().credential( withVerificationID: verificationId, verificationCode: verificationCode)
Objectif c
// Ask user for the SMS verification code. Then: FIRPhoneAuthCredential *credential = [FIRPhoneAuthProvider.provider credentialWithVerificationID:verificationID verificationCode:kPhoneSecondFactorVerificationCode];
Initialisez un objet d'assertion :
Rapide
let assertion = PhoneMultiFactorGenerator.assertion(with: credential)
Objectif c
FIRMultiFactorAssertion *assertion = [FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
Complétez l'inscription. Si vous le souhaitez, vous pouvez spécifier un nom d'affichage pour le deuxième facteur. Ceci est utile pour les utilisateurs avec plusieurs seconds facteurs, car le numéro de téléphone est masqué pendant le flux d'authentification (par exemple, +1******1234).
Rapide
// Complete enrollment. This will update the underlying tokens // and trigger ID token change listener. user.multiFactor.enroll(with: assertion, displayName: displayName) { (error) in // ... }
Objectif c
// Complete enrollment. This will update the underlying tokens // and trigger ID token change listener. [authResult.user.multiFactor enrollWithAssertion:assertion displayName:nil completion:^(NSError * _Nullable error) { // ... }];
Le code ci-dessous montre un exemple complet d'inscription d'un deuxième facteur :
Rapide
let user = Auth.auth().currentUser
user?.multiFactor.getSessionWithCompletion({ (session, error) in
// Send SMS verification code.
PhoneAuthProvider.provider().verifyPhoneNumber(
phoneNumber,
uiDelegate: nil,
multiFactorSession: session
) { (verificationId, error) in
// verificationId will be needed for enrollment completion.
// Ask user for the verification code.
let credential = PhoneAuthProvider.provider().credential(
withVerificationID: verificationId!,
verificationCode: phoneSecondFactorVerificationCode)
let assertion = PhoneMultiFactorGenerator.assertion(with: credential)
// Complete enrollment. This will update the underlying tokens
// and trigger ID token change listener.
user?.multiFactor.enroll(with: assertion, displayName: displayName) { (error) in
// ...
}
}
})
Objectif c
FIRUser *user = FIRAuth.auth.currentUser;
[user.multiFactor getSessionWithCompletion:^(FIRMultiFactorSession * _Nullable session,
NSError * _Nullable error) {
// Send SMS verification code.
[FIRPhoneAuthProvider.provider
verifyPhoneNumber:phoneNumber
UIDelegate:nil
multiFactorSession:session
completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) {
// verificationId will be needed for enrollment completion.
// Ask user for the verification code.
// ...
// Then:
FIRPhoneAuthCredential *credential =
[FIRPhoneAuthProvider.provider credentialWithVerificationID:verificationID
verificationCode:kPhoneSecondFactorVerificationCode];
FIRMultiFactorAssertion *assertion =
[FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
// Complete enrollment. This will update the underlying tokens
// and trigger ID token change listener.
[user.multiFactor enrollWithAssertion:assertion
displayName:displayName
completion:^(NSError * _Nullable error) {
// ...
}];
}];
}];
Toutes nos félicitations! Vous avez enregistré avec succès un deuxième facteur d'authentification pour un utilisateur.
Connexion des utilisateurs avec un deuxième facteur
Pour connecter un utilisateur avec la vérification par SMS à deux facteurs :
Connectez l'utilisateur avec son premier facteur, puis détectez une erreur indiquant qu'une authentification multifacteur est requise. Cette erreur contient un résolveur, des indices sur les seconds facteurs inscrits et une session sous-jacente prouvant que l'utilisateur s'est authentifié avec succès avec le premier facteur.
Par exemple, si le premier facteur de l'utilisateur était une adresse e-mail et un mot de passe :
Rapide
Auth.auth().signIn( withEmail: email, password: password ) { (result, error) in let authError = error as NSError if authError?.code == AuthErrorCode.secondFactorRequired.rawValue { // The user is a multi-factor user. Second factor challenge is required. let resolver = authError!.userInfo[AuthErrorUserInfoMultiFactorResolverKey] as! MultiFactorResolver // ... } else { // Handle other errors such as wrong password. } }
Objectif c
[FIRAuth.auth signInWithEmail:email password:password completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { if (error == nil || error.code != FIRAuthErrorCodeSecondFactorRequired) { // User is not enrolled with a second factor and is successfully signed in. // ... } else { // The user is a multi-factor user. Second factor challenge is required. } }];
Si le premier facteur de l'utilisateur est un fournisseur fédéré, tel que OAuth, interceptez l'erreur après avoir appelé
getCredentialWith()
.Si l'utilisateur a inscrit plusieurs facteurs secondaires, demandez-lui lequel utiliser. Vous pouvez obtenir le numéro de téléphone masqué avec
resolver.hints[selectedIndex].phoneNumber
et le nom d'affichage avecresolver.hints[selectedIndex].displayName
.Rapide
// Ask user which second factor to use. Then: if resolver.hints[selectedIndex].factorID == PhoneMultiFactorID { // User selected a phone second factor. // ... } else if resolver.hints[selectedIndex].factorID == TotpMultiFactorID { // User selected a TOTP second factor. // ... } else { // Unsupported second factor. }
Objectif c
FIRMultiFactorResolver *resolver = (FIRMultiFactorResolver *) error.userInfo[FIRAuthErrorUserInfoMultiFactorResolverKey]; // Ask user which second factor to use. Then: FIRPhoneMultiFactorInfo *hint = (FIRPhoneMultiFactorInfo *) resolver.hints[selectedIndex]; if (hint.factorID == FIRPhoneMultiFactorID) { // User selected a phone second factor. // ... } else if (hint.factorID == FIRTOTPMultiFactorID) { // User selected a TOTP second factor. // ... } else { // Unsupported second factor. }
Envoyez un message de vérification au téléphone de l'utilisateur :
Rapide
// Send SMS verification code. let hint = resolver.hints[selectedIndex] as! PhoneMultiFactorInfo PhoneAuthProvider.provider().verifyPhoneNumber( with: hint, uiDelegate: nil, multiFactorSession: resolver.session ) { (verificationId, error) in // verificationId will be needed for sign-in completion. }
Objectif c
// Send SMS verification code [FIRPhoneAuthProvider.provider verifyPhoneNumberWithMultiFactorInfo:hint UIDelegate:nil multiFactorSession:resolver.session completion:^(NSString * _Nullable verificationID, NSError * _Nullable error) { if (error != nil) { // Failed to verify phone number. } }];
Une fois le code SMS envoyé, demandez à l'utilisateur de vérifier le code et de l'utiliser pour créer un
PhoneAuthCredential
:Rapide
// Ask user for the verification code. Then: let credential = PhoneAuthProvider.provider().credential( withVerificationID: verificationId!, verificationCode: verificationCodeFromUser)
Objectif c
// Ask user for the SMS verification code. Then: FIRPhoneAuthCredential *credential = [FIRPhoneAuthProvider.provider credentialWithVerificationID:verificationID verificationCode:verificationCodeFromUser];
Initialisez un objet d'assertion avec les informations d'identification :
Rapide
let assertion = PhoneMultiFactorGenerator.assertion(with: credential)
Objectif c
FIRMultiFactorAssertion *assertion = [FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
Résolvez la connexion. Vous pouvez ensuite accéder au résultat de connexion d'origine, qui inclut les données standard spécifiques au fournisseur et les identifiants d'authentification :
Rapide
// Complete sign-in. This will also trigger the Auth state listeners. resolver.resolveSignIn(with: assertion) { (authResult, error) in // authResult will also contain the user, additionalUserInfo, optional // credential (null for email/password) associated with the first factor sign-in. // For example, if the user signed in with Google as a first factor, // authResult.additionalUserInfo will contain data related to Google provider that // the user signed in with. // user.credential contains the Google OAuth credential. // user.credential.accessToken contains the Google OAuth access token. // user.credential.idToken contains the Google OAuth ID token. }
Objectif c
// Complete sign-in. [resolver resolveSignInWithAssertion:assertion completion:^(FIRAuthDataResult * _Nullable authResult, NSError * _Nullable error) { if (error != nil) { // User successfully signed in with the second factor phone number. } }];
Le code ci-dessous montre un exemple complet de connexion d'un utilisateur multifacteur :
Rapide
Auth.auth().signIn(
withEmail: email,
password: password
) { (result, error) in
let authError = error as NSError?
if authError?.code == AuthErrorCode.secondFactorRequired.rawValue {
let resolver =
authError!.userInfo[AuthErrorUserInfoMultiFactorResolverKey] as! MultiFactorResolver
// Ask user which second factor to use.
// ...
// Then:
let hint = resolver.hints[selectedIndex] as! PhoneMultiFactorInfo
// Send SMS verification code
PhoneAuthProvider.provider().verifyPhoneNumber(
with: hint,
uiDelegate: nil,
multiFactorSession: resolver.session
) { (verificationId, error) in
if error != nil {
// Failed to verify phone number.
}
// Ask user for the SMS verification code.
// ...
// Then:
let credential = PhoneAuthProvider.provider().credential(
withVerificationID: verificationId!,
verificationCode: verificationCodeFromUser)
let assertion = PhoneMultiFactorGenerator.assertion(with: credential)
// Complete sign-in.
resolver.resolveSignIn(with: assertion) { (authResult, error) in
if error != nil {
// User successfully signed in with the second factor phone number.
}
}
}
}
}
Objectif c
[FIRAuth.auth signInWithEmail:email
password:password
completion:^(FIRAuthDataResult * _Nullable authResult,
NSError * _Nullable error) {
if (error == nil || error.code != FIRAuthErrorCodeSecondFactorRequired) {
// User is not enrolled with a second factor and is successfully signed in.
// ...
} else {
FIRMultiFactorResolver *resolver =
(FIRMultiFactorResolver *) error.userInfo[FIRAuthErrorUserInfoMultiFactorResolverKey];
// Ask user which second factor to use.
// ...
// Then:
FIRPhoneMultiFactorInfo *hint = (FIRPhoneMultiFactorInfo *) resolver.hints[selectedIndex];
// Send SMS verification code
[FIRPhoneAuthProvider.provider
verifyPhoneNumberWithMultiFactorInfo:hint
UIDelegate:nil
multiFactorSession:resolver.session
completion:^(NSString * _Nullable verificationID,
NSError * _Nullable error) {
if (error != nil) {
// Failed to verify phone number.
}
// Ask user for the SMS verification code.
// ...
// Then:
FIRPhoneAuthCredential *credential =
[FIRPhoneAuthProvider.provider
credentialWithVerificationID:verificationID
verificationCode:kPhoneSecondFactorVerificationCode];
FIRMultiFactorAssertion *assertion =
[FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
// Complete sign-in.
[resolver resolveSignInWithAssertion:assertion
completion:^(FIRAuthDataResult * _Nullable authResult,
NSError * _Nullable error) {
if (error != nil) {
// User successfully signed in with the second factor phone number.
}
}];
}];
}
}];
Toutes nos félicitations! Vous avez réussi à connecter un utilisateur à l'aide de l'authentification multifacteur.
Et après
- Gérez les utilisateurs multi-facteurs par programmation avec le SDK Admin.