Wenn Sie ein Upgrade auf Firebase Authentication mit Identity Platform durchgeführt haben, können Sie Ihrer iOS-App die mehrstufige SMS-Authentifizierung hinzufügen.
Die Multi-Faktor-Authentifizierung erhöht die Sicherheit Ihrer App. Während Angreifer oft Passwörter und soziale Konten kompromittieren, ist das Abfangen einer Textnachricht schwieriger.
Bevor Sie beginnen
Aktivieren Sie mindestens einen Anbieter, der die mehrstufige Authentifizierung unterstützt. Jeder Anbieter unterstützt MFA, außer Telefonauthentifizierung, anonyme Authentifizierung und Apple Game Center.
Stellen Sie sicher, dass Ihre App Benutzer-E-Mails überprüft. MFA erfordert eine E-Mail-Bestätigung. Dies verhindert, dass böswillige Akteure sich mit einer E-Mail-Adresse, die ihnen nicht gehört, für einen Dienst registrieren und dann den wahren Eigentümer aussperren, indem sie einen zweiten Faktor hinzufügen.
Multi-Faktor-Authentifizierung aktivieren
Öffnen Sie die Seite Authentifizierung > Anmeldemethode der Firebase- Konsole.
Aktivieren Sie im Abschnitt „ Erweitert “ die SMS-Multi-Faktor-Authentifizierung .
Sie sollten auch die Telefonnummern eingeben, mit denen Sie Ihre App testen werden. Obwohl optional, wird die Registrierung von Testtelefonnummern dringend empfohlen, um eine Drosselung während der Entwicklung zu vermeiden.
Wenn Sie die Domäne Ihrer App noch nicht autorisiert haben, fügen Sie sie der Zulassungsliste auf der Seite Authentifizierung > Einstellungen der Firebase-Konsole hinzu.
Überprüfung Ihrer App
Firebase muss überprüfen, ob SMS-Anfragen von Ihrer App stammen. Sie können dies auf zwei Arten tun:
Stille APNs-Benachrichtigungen : Wenn Sie einen Benutzer zum ersten Mal anmelden, kann Firebase eine stille Push-Benachrichtigung an das Gerät des Benutzers senden. Die Authentifizierung kann fortgesetzt werden, wenn die App die Benachrichtigung erhält. Beachten Sie, dass Sie ab iOS 8.0 den Benutzer nicht bitten müssen, Push-Benachrichtigungen zuzulassen, um diese Methode zu verwenden.
reCAPTCHA-Überprüfung : Wenn Sie keine stille Benachrichtigung senden können (z. B. weil der Benutzer die Hintergrundaktualisierung deaktiviert hat oder Sie Ihre App im iOS-Simulator testen), können Sie reCAPTCHA verwenden. In vielen Fällen löst sich das reCAPTCHA automatisch ohne Benutzerinteraktion.
Verwenden von stillen Benachrichtigungen
So aktivieren Sie APNs-Benachrichtigungen für die Verwendung mit Firebase:
Aktivieren Sie in Xcode Push-Benachrichtigungen für Ihr Projekt.
Laden Sie Ihren APNs-Authentifizierungsschlüssel über die Firebase-Konsole hoch (Ihre Änderungen werden automatisch auf Google Cloud Firebase übertragen). Wenn Sie Ihren APNs-Authentifizierungsschlüssel noch nicht haben, erfahren Sie unter Konfigurieren von APNs mit FCM , wie Sie ihn erhalten.
Öffnen Sie die Firebase-Konsole .
Navigieren Sie zu Projekteinstellungen .
Wählen Sie die Registerkarte Cloud-Messaging aus.
Klicken Sie unter APNs-Authentifizierungsschlüssel im Konfigurationsabschnitt der iOS-App auf Hochladen .
Wählen Sie Ihren Schlüssel aus.
Fügen Sie die Schlüssel-ID für den Schlüssel hinzu. Die Schlüssel-ID finden Sie im Apple Developer Member Center unter Certificates, Identifiers & Profiles .
Klicken Sie auf Hochladen .
Wenn Sie bereits über ein APNs-Zertifikat verfügen, können Sie stattdessen das Zertifikat hochladen.
Verwendung der reCAPTCHA-Überprüfung
So aktivieren Sie das Client-SDK zur Verwendung von reCAPTCHA:
Öffnen Sie Ihre Projektkonfiguration in Xcode.
Doppelklicken Sie in der linken Baumansicht auf den Projektnamen.
Wählen Sie Ihre App aus dem Abschnitt „ Ziele “ aus.
Wählen Sie die Registerkarte Info .
Erweitern Sie den Abschnitt URL-Typen .
Klicken Sie auf die Schaltfläche + .
Geben Sie Ihre umgekehrte Client-ID in das Feld URL-Schemata ein. Sie finden diesen Wert in der Konfigurationsdatei
GoogleService-Info.plist
alsREVERSED_CLIENT_ID
.
Wenn Sie fertig sind, sollte Ihre Konfiguration etwa so aussehen:
Optional können Sie die Art und Weise anpassen, wie Ihre App den SFSafariViewController
oder UIWebView
, wenn das reCAPTCHA angezeigt wird. Erstellen Sie dazu eine benutzerdefinierte Klasse, die dem FIRAuthUIDelegate
Protokoll entspricht, und übergeben Sie sie an verifyPhoneNumber:UIDelegate:completion:
.
Auswählen eines Registrierungsmusters
Sie können wählen, ob Ihre App eine mehrstufige Authentifizierung erfordert und wie und wann Sie Ihre Benutzer registrieren. Einige gängige Muster sind:
Registrieren Sie den zweiten Faktor des Benutzers als Teil der Registrierung. Verwenden Sie diese Methode, wenn Ihre App eine mehrstufige Authentifizierung für alle Benutzer erfordert. Beachten Sie, dass ein Konto über eine verifizierte E-Mail-Adresse verfügen muss, um einen zweiten Faktor zu registrieren, sodass Ihr Registrierungsablauf dies berücksichtigen muss.
Bieten Sie eine überspringbare Option an, um während der Registrierung einen zweiten Faktor zu registrieren. Apps, die die mehrstufige Authentifizierung fördern, aber nicht verlangen möchten, bevorzugen möglicherweise diesen Ansatz.
Bieten Sie die Möglichkeit, einen zweiten Faktor von der Konto- oder Profilverwaltungsseite des Benutzers anstelle des Anmeldebildschirms hinzuzufügen. Dies minimiert Reibungsverluste während des Registrierungsprozesses und stellt gleichzeitig die Multi-Faktor-Authentifizierung für sicherheitssensible Benutzer zur Verfügung.
Erfordern Sie das schrittweise Hinzufügen eines zweiten Faktors, wenn der Benutzer auf Funktionen mit erhöhten Sicherheitsanforderungen zugreifen möchte.
Registrierung eines zweiten Faktors
So registrieren Sie einen neuen sekundären Faktor für einen Benutzer:
Authentifizieren Sie den Benutzer erneut.
Bitten Sie den Benutzer, seine Telefonnummer einzugeben.
Holen Sie sich eine Multi-Faktor-Sitzung für den Benutzer:
Schnell
authResult.user.multiFactor.getSessionWithCompletion() { (session, error) in // ... }
Ziel c
[authResult.user.multiFactor getSessionWithCompletion:^(FIRMultiFactorSession * _Nullable session, NSError * _Nullable error) { // ... }];
Senden Sie eine Bestätigungsnachricht an das Telefon des Benutzers. Stellen Sie sicher, dass die Telefonnummer mit einem führenden
+
und ohne andere Satzzeichen oder Leerzeichen formatiert ist (z. B.:+15105551234
)Schnell
// Send SMS verification code. PhoneAuthProvider.provider().verifyPhoneNumber( phoneNumber, uiDelegate: nil, multiFactorSession: session) { (verificationId, error) in // verificationId will be needed for enrollment completion. }
Ziel 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. }];
Obwohl dies nicht erforderlich ist, empfiehlt es sich, Benutzer im Voraus darüber zu informieren, dass sie eine SMS-Nachricht erhalten und dass Standardtarife gelten.
Die Methode
verifyPhoneNumber()
startet den App-Überprüfungsprozess im Hintergrund mit stiller Push-Benachrichtigung. Wenn keine stille Push-Benachrichtigung verfügbar ist, wird stattdessen eine reCAPTCHA-Aufforderung ausgegeben.Sobald der SMS-Code gesendet wurde, bitten Sie den Benutzer, den Code zu bestätigen. Verwenden Sie dann ihre Antwort, um ein
PhoneAuthCredential
zu erstellen:Schnell
// Ask user for the verification code. Then: let credential = PhoneAuthProvider.provider().credential( withVerificationID: verificationId, verificationCode: verificationCode)
Ziel c
// Ask user for the SMS verification code. Then: FIRPhoneAuthCredential *credential = [FIRPhoneAuthProvider.provider credentialWithVerificationID:verificationID verificationCode:kPhoneSecondFactorVerificationCode];
Initialisieren Sie ein Assertion-Objekt:
Schnell
let assertion = PhoneMultiFactorGenerator.assertion(with: credential)
Ziel c
FIRMultiFactorAssertion *assertion = [FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
Schließen Sie die Registrierung ab. Optional können Sie einen Anzeigenamen für den zweiten Faktor angeben. Dies ist nützlich für Benutzer mit mehreren Sekundenfaktoren, da die Telefonnummer während des Authentifizierungsflusses maskiert wird (z. B. +1******1234).
Schnell
// Complete enrollment. This will update the underlying tokens // and trigger ID token change listener. user.multiFactor.enroll(with: assertion, displayName: displayName) { (error) in // ... }
Ziel 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) { // ... }];
Der folgende Code zeigt ein vollständiges Beispiel für die Registrierung eines zweiten Faktors:
Schnell
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
// ...
}
}
})
Ziel 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) {
// ...
}];
}];
}];
Glückwünsche! Sie haben erfolgreich einen zweiten Authentifizierungsfaktor für einen Benutzer registriert.
Anmelden von Benutzern mit einem zweiten Faktor
So melden Sie einen Benutzer mit Zwei-Faktor-SMS-Bestätigung an:
Melden Sie den Benutzer mit seinem ersten Faktor an und fangen Sie dann einen Fehler ab, der angibt, dass eine mehrstufige Authentifizierung erforderlich ist. Dieser Fehler enthält einen Resolver, Hinweise auf die registrierten zweiten Faktoren und eine zugrunde liegende Sitzung, die beweist, dass sich der Benutzer erfolgreich mit dem ersten Faktor authentifiziert hat.
Wenn der erste Faktor des Benutzers beispielsweise eine E-Mail-Adresse und ein Passwort war:
Schnell
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. } }
Ziel 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. } }];
Wenn der erste Faktor des Benutzers ein Verbundanbieter wie OAuth ist, fangen Sie den Fehler nach dem Aufrufen
getCredentialWith()
.Wenn der Benutzer mehrere sekundäre Faktoren registriert hat, fragen Sie ihn, welchen er verwenden soll. Die maskierte Telefonnummer erhalten Sie mit
resolver.hints[selectedIndex].phoneNumber
und den Anzeigenamen mitresolver.hints[selectedIndex].displayName
.Schnell
// 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. }
Ziel 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. }
Senden Sie eine Bestätigungsnachricht an das Telefon des Benutzers:
Schnell
// 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. }
Ziel 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. } }];
Sobald der SMS-Code gesendet wurde, bitten Sie den Benutzer, den Code zu überprüfen und ihn zum Erstellen eines
PhoneAuthCredential
zu verwenden:Schnell
// Ask user for the verification code. Then: let credential = PhoneAuthProvider.provider().credential( withVerificationID: verificationId!, verificationCode: verificationCodeFromUser)
Ziel c
// Ask user for the SMS verification code. Then: FIRPhoneAuthCredential *credential = [FIRPhoneAuthProvider.provider credentialWithVerificationID:verificationID verificationCode:verificationCodeFromUser];
Initialisieren Sie ein Assertion-Objekt mit den Anmeldeinformationen:
Schnell
let assertion = PhoneMultiFactorGenerator.assertion(with: credential)
Ziel c
FIRMultiFactorAssertion *assertion = [FIRPhoneMultiFactorGenerator assertionWithCredential:credential];
Lösen Sie die Anmeldung auf. Sie können dann auf das ursprüngliche Anmeldeergebnis zugreifen, das die standardmäßigen anbieterspezifischen Daten und Authentifizierungsdaten enthält:
Schnell
// 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. }
Ziel 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. } }];
Der folgende Code zeigt ein vollständiges Beispiel für die Anmeldung eines Multi-Factor-Benutzers:
Schnell
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.
}
}
}
}
}
Ziel 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.
}
}];
}];
}
}];
Glückwünsche! Sie haben einen Benutzer erfolgreich mit Multi-Faktor-Authentifizierung angemeldet.
Was kommt als nächstes
- Verwalten Sie Multi-Factor-Benutzer programmgesteuert mit dem Admin SDK.