Tutorial: An- und Abmeldung in iOS/macOS-App mit nativer Authentifizierung hinzufügen
Gilt für: iOS (Swift) macOS (Swift)
Dieses Tutorial demonstriert, wie man einen Benutzer mit einem einmaligen E-Mail-Passcode oder einem Benutzernamen und einem Passwort in einer iOS/macOS-App unter Verwendung der nativen Authentifizierung anmeldet und abmeldet.
In diesem Tutorial lernen Sie Folgendes:
- Melden Sie einen Benutzer mithilfe eines E-Mail-Einmal-Passcodes oder mit Benutzername (E-Mail-Adresse) und Kennwort an.
- Abmelden eines Benutzenden.
- Behandeln von Anmeldefehlern
Voraussetzungen
- Tutorial: Bereiten Sie Ihre iOS/macOS-App für die native Authentifizierung vor.
- Wenn Sie sich per E-Mail mit Kennwort anmelden möchten, konfigurieren Sie den Benutzerflow so, dass E-Mail mit Kennwort verwendet wird, wenn Sie Ihren Flow für die Registrierung und Anmeldung von Benutzern erstellen.
Anmeldung für Benutzer
Wenn Sie eine(n) Benutzer*in mithilfe des E-Mail Einmal-Passcodes anmelden möchten, erfassen Sie die E-Mail, und senden Sie eine E-Mail, die einen Einmal-Passcode enthält, damit der/die Benutzer*in seine/ihre E-Mails überprüfen kann. Wenn der Benutzende einen gültigen Einmal-Passcode eingibt, meldet die App ihn an.
Wenn Sie einen Benutzer über den Flow E-Mail-Adresse mit Kennwort anmelden möchten, erfassen Sie die E-Mail-Adresse und das Kennwort. Wenn der Benutzername und das Kennwort gültig sind, meldet sich die App beim Benutzer an.
Um sich bei einem Benutzer anzumelden, müssen Sie:
Eine Benutzeroberfläche für Folgendes erstellen:
- Erfassen einer E-Mail-Adresse des Benutzers. Fügen Sie eine Validierung für die Eingaben hinzu, um sicherzustellen, dass der Benutzer eine gültige E-Mail-Adresse eingibt.
- Erfassen eines Kennworts, wenn das Anmelden mit Benutzername (E-Mail-Adresse) und Kennwort erfolgt.
- Sammeln Sie eine einmal vom Benutzer gesendete E-Mail-Kennung, wenn Sie sich mit einer Einmalkennung per E-Mail anmelden.
- Fügen Sie eine Schaltfläche hinzu, damit der Benutzer den Einmal-Passcode erneut senden kann, wenn Sie sich mit einem Einmal-Passcode per E-Mail anmelden.
Fügen Sie auf der Benutzeroberfläche eine Schaltfläche hinzu, deren Auswahlereignis eine Anmeldung startet, wie im folgenden Codeschnipsel gezeigt:
@IBAction func signInPressed(_: Any) { guard let email = emailTextField.text else { resultTextView.text = "email not set" return } nativeAuth.signIn(username: email, delegate: self) }
Zum Anmelden eines Benutzers über den Flow E-Mail-Einmal-Passcode verwenden wir den folgenden Codeschnipsel:
nativeAuth.signIn(username: email, delegate: self)
Die
signIn(username:delegate)
-Methode, die asynchron reagiert, indem eine der Methoden für das übergebene Delegatobjekt aufgerufen wird, muss dasSignInStartDelegate
-Protokoll implementieren. Wir übergeben die E-Mail-Adresse, die der/die Benutzer*in im E-Mail-Übermittlungsformular bereitstellt, und übergeben sieself
als Delegate.Wenn Sie einen Benutzer über den Flow E-Mail-Adresse mit Kennwort anmelden möchten, verwenden Sie den folgenden Codeschnipsel:
nativeAuth.signIn(username: email, password: password, delegate: self)
In der
signIn(username:password:delegate)
-Methode übergeben Sie die E-Mail-Adresse, die der Benutzer uns zur Verfügung gestellt hat, sein Kennwort und das Delegatobjekt, das demSignInStartDelegate
-Protokoll entspricht. In diesem Beispiel übergeben wirself
.Verwenden Sie den folgenden Codeschnipsel, um das
SignInStartDelegate
-Protokoll zu implementieren, wenn Sie den Flow E-Mail-Einmal-Passcode verwenden:extension ViewController: SignInStartDelegate { func onSignInStartError(error: MSAL.SignInStartError) { resultTextView.text = "Error signing in: \(error.errorDescription ?? "no description")" } func onSignInCodeRequired( newState: MSAL.SignInCodeRequiredState, sentTo: String, channelTargetType: MSAL.MSALNativeAuthChannelType, codeLength: Int ) { resultTextView.text = "Verification code sent to \(sentTo)" } }
Das
signIn(username:delegate)
Ergebnis ist ein Aufruf der Delegatmethoden. Im häufigsten Szenario wirdonSignInCodeRequired(newState:sentTo:channelTargetType:codeLength)
aufgerufen, um anzugeben, dass ein Code gesendet wurde, um die E-Mail-Adresse des Benutzers/der Benutzerin zu überprüfen. Zusammen mit einigen Details dazu, wo der Code gesendet wurde und wie viele Ziffern er enthält, verfügt diese Delegatmethode auch über einennewState
Parameter vom TypSignInCodeRequiredState
, der uns Zugriff auf die folgenden beiden neuen Methoden gibt:submitCode(code:delegate)
resendCode(delegate)
Zur Verwendung von
submitCode(code:delegate)
zum Übermitteln des Einmal-Passcodes, den der Benutzer im Einmal-Passcode-Formular bereitstellt, verwenden Sie den folgenden Codeschnipsel:newState.submitCode(code: userSuppliedCode, delegate: self)
submitCode(code:delegate)
akzeptiert den Einmal-Passcode- und Delegatparameter. Nach Übermittlung des Codes müssen Sie den Einmal-Passcode überprüfen, indem Sie dasSignInVerifyCodeDelegate
Protokoll implementieren.Verwenden Sie den folgenden Codeausschnitt, um das
SignInVerifyCodeDelegate
Protokoll als Erweiterung für Ihre Klasse zu implementieren:extension ViewController: SignInVerifyCodeDelegate { func onSignInVerifyCodeError(error: MSAL.VerifyCodeError, newState: MSAL.SignInCodeRequiredState?) { resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")" } func onSignInCompleted(result: MSALNativeAuthUserAccountResult) { resultTextView.text = "Signed in successfully." result.getAccessToken(delegate: self) } }
Im häufigsten Szenario erhalten wir einen Aufruf von
onSignInCompleted(result)
, der angibt, dass sich der Benutzer angemeldet hat. Das Ergebnis kann zum Abrufen desaccess token
verwendet werden.getAccessToken(delegate)
akzeptiert einen Delegatparameter, und wir müssen die erforderlichen Methoden im ProtokollCredentialsDelegate
implementieren.Im häufigsten Szenario erhalten wir einen Aufruf von
onAccessTokenRetrieveCompleted(result)
, der angibt, dass der Benutzer einaccess token
erhalten hat.extension ViewController: CredentialsDelegate { func onAccessTokenRetrieveError(error: MSAL.RetrieveAccessTokenError) { resultTextView.text = "Error retrieving access token" } func onAccessTokenRetrieveCompleted(result: MSALNativeAuthTokenResult) { resultTextView.text = "Signed in. Access Token: \(result.accessToken)" } }
Verwenden Sie den folgenden Codeschnipsel, um das
SignInStartDelegate
-Protokoll zu implementieren, wenn Sie den Flow E-Mail-Adresse mit Kennwort verwenden:extension ViewController: SignInStartDelegate { func onSignInStartError(error: MSAL.SignInStartError) { resultTextView.text = "Error signing in: \(error.errorDescription ?? "no description")" } func onSignInCompleted(result: MSAL.MSALNativeAuthUserAccountResult) { // User successfully signed in } }
Im häufigsten Szenario erhalten wir einen Aufruf von
onSignInCompleted(result)
, der angibt, dass sich der Benutzer angemeldet hat. Das Ergebnis kann zum Abrufen desaccess token
verwendet werden.getAccessToken(delegate)
akzeptiert einen Delegatparameter, und wir müssen die erforderlichen Methoden im ProtokollCredentialsDelegate
implementieren.Im häufigsten Szenario erhalten wir einen Aufruf von
onAccessTokenRetrieveCompleted(result)
, der angibt, dass der Benutzer einaccess token
erhalten hat.extension ViewController: CredentialsDelegate { func onAccessTokenRetrieveError(error: MSAL.RetrieveAccessTokenError) { resultTextView.text = "Error retrieving access token" } func onAccessTokenRetrieveCompleted(result: MSALNativeAuthTokenResult) { resultTextView.text = "Signed in. Access Token: \(result.accessToken)" } }
Behandeln von Anmeldefehlern
Bei der Anmeldung ist nicht jede Aktion erfolgreich. Beispielsweise kann der/die Benutzer*in versuchen, sich mit einer E-Mail-Adresse anzumelden, die nicht vorhanden ist, oder einen ungültigen Code übermitteln.
Verwenden Sie den folgenden Codeschnipsel, um Fehler bei der Methode
signIn(username)
odersignIn(username, password)
zu behandeln:func onSignInStartError(error: MSAL.SignInStartError) { if error.isUserNotFound || error.isInvalidUsername { resultTextView.text = "Invalid username" } else { resultTextView.text = "Error signing in: \(error.errorDescription ?? "no description")" } }
Verwenden Sie den folgenden Codeschnipsel, um Fehler bei der Methode
submitCode()
zu behandeln:func onSignInVerifyCodeError(error: MSAL.VerifyCodeError, newState: MSAL.SignInCodeRequiredState?) { if error.isInvalidCode { // Inform the user that the submitted code was incorrect and ask for a new code to be supplied let userSuppliedCode = retrieveNewCode() newState?.submitCode(code: userSuppliedCode, delegate: self) } else { resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")" } }
Wenn der/die Benutzer*in einen falschen E-Mail-Überprüfungscode eingibt, enthält der Fehlerhandler einen Verweis auf einen
SignInCodeRequiredState
, der für die Übermittlung eines aktualisierten Codes verwendet werden kann. In unserer früheren Implementierung desSignInVerifyCodeDelegate
Protokolls haben wir einfach den Fehler angezeigt, wenn wir dieonSignInVerifyCodeError(error:newState)
Delegatfunktion behandelt haben.
Lesen von ID-Tokenansprüchen
Sobald Ihre App ein ID-Token abruft, können Sie die dem aktuellen Konto zugeordneten Ansprüche abrufen. Verwenden Sie dazu den folgenden Codeschnipsel:
func onSignInCompleted(result: MSAL.MSALNativeAuthUserAccountResult) {
let claims = result.account.accountClaims
let preferredUsername = claims?["preferred_username"] as? String
}
Der Schlüssel, den Sie für den Zugriff auf den Anspruchswert verwenden, ist der Name, den Sie beim Hinzufügen des Benutzerattributs als Tokenanspruch angeben.
Informationen zum Hinzufügen integrierter und benutzerdefinierter Attribute als Tokenansprüche finden Sie im Artikel Hinzufügen von Benutzerattributen zu Tokenansprüchen.
Abmelden des Benutzers
Verwenden Sie zum Abmelden eines Benutzers/einer Benutzerin den Verweis auf den MSALNativeAuthUserAccountResult
im Rückruf empfangenen onSignInCompleted
Verweis, oder verwenden getNativeAuthUserAccount()
Sie den Verweis, um ein angemeldetes Konto aus dem Zwischenspeicher abzurufen und einen Verweis in der accountResult
Membervariable zu speichern.
Konfigurieren Sie die Schlüsselbundgruppe für Ihr Projekt wie hier beschrieben.
Fügen Sie ihrer
ViewController
Klassevar accountResult: MSALNativeAuthUserAccountResult?
eine neue Membervariable hinzu:Aktualisieren Sie
viewDidLoad
, um alle zwischengespeicherten Konten abzurufen, indem Sie diese Zeile nachnativeAuth
der Initialisierung erfolgreich hinzufügen:accountResult = nativeAuth.getNativeAuthUserAccount()
.Aktualisieren Sie den
signInCompleted
Handler, um das Kontoergebnis zu speichern:func onSignInCompleted(result: MSALNativeAuthUserAccountResult) { resultTextView.text = "Signed in successfully" accountResult = result }
Fügen Sie eine Schaltfläche Für Abmelden hinzu, und verwenden Sie den folgenden Code, um den/die Benutzer*in abzumelden:
@IBAction func signOutPressed(_: Any) { guard let accountResult = accountResult else { print("Not currently signed in") return } accountResult.signOut() self.accountResult = nil resultTextView.text = "Signed out" }
Sie haben alle erforderlichen Schritte zum Abmelden eines Benutzers/einer Benutzerin in Ihrer App erfolgreich abgeschlossen. Erstellen Sie Ihre Anwendung, und führen Sie sie aus. Wenn alles gut ist, sollten Sie die Schaltfläche Abmelden auswählen können, um sich erfolgreich abzumelden.
Konfigurieren eines benutzerdefinierten Anspruchsanbieters
Wenn Sie Ansprüche aus einem externen System in das Token einfügen möchten, das an Ihre Anwendung ausgegeben wird, verwenden Sie einen benutzerdefinierten Anspruchsanbieter. Ein benutzerdefinierter Anspruchsanbieter besteht aus einer benutzerdefinierten Authentifizierungserweiterung, die eine externe REST-API aufruft, um Ansprüche aus externen Systemen abzurufen.
Führen Sie die Schritte unter Konfigurieren eines benutzerdefinierten Anspruchsanbieters durch, um Ansprüche aus einem externen System zu Ihren Sicherheitstoken hinzuzufügen.