Tutorial: Anmeldung in einer iOS/macOS App mit nativer Authentifizierung hinzufügen
Gilt für: iOS (Swift) macOS (Swift)
Dieses Tutorial zeigt, wie Sie einen Benutzer mit einem einmaligen E-Mail-Passcode oder einem Benutzernamen (E-Mail) und einem Passwort registrieren und Benutzerattribute in Ihrer iOS/macOS App mit nativer Authentifizierung erfassen.
- Registrieren Sie einen Benutzer mithilfe eines E-Mail-Einmal-Passcodes oder mit Benutzername (E-Mail-Adresse) und Kennwort.
- Erfassen von Benutzerattributen während der Registrierung.
- Behandeln von Registrierungsfehlern
Voraussetzungen
- Tutorial: Bereiten Sie Ihre iOS/macOS-App für die native Authentifizierung vor.
- Wenn Sie während der Registrierung Benutzerattribute erfassen möchten, konfigurieren Sie die Benutzerattribute, wenn Sie Ihren Flow für die Registrierung und Anmeldung von Benutzern erstellen.
Registrieren eines Benutzers
Um einen Benutzer mithilfe des E-Mail-Einmal-Passcodes oder mit Benutzername (E-Mail-Adresse) und Kennwort zu registrieren, erfassen Sie eine E-Mail-Adresse des Benutzers und senden ihm eine E-Mail mit einem E-Mail-Einmal-Passcode. Der Benutzer gibt einen gültigen E-Mail-Einmal-Passcode ein, um seinen Benutzernamen zu validieren.
Zum Registrieren eines Benutzers 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 die Registrierung mit Benutzername (E-Mail-Adresse) und Kennwort erfolgt
- Erfassen eines E-Mail-Einmal-Passcodes vom Benutzer
- Erfassen von Benutzerattributen bei Bedarf
- Erneutes Senden des Einmal-Passcodes, wenn der Benutzer ihn nicht empfängt
- Starten des Registrierungsflows
Fügen Sie in Ihrer App eine Schaltfläche hinzu, deren Auswahlereignis den folgenden Codeschnipsel auslöst:
@IBAction func signUpPressed(_: Any) { guard let email = emailTextField.text else { resultTextView.text = "Email or password not set" return } nativeAuth.signUp(username: email, delegate: self) }
Zum Registrieren eines Benutzers mithilfe eines E-Mail-Einmal-Passcodes verwenden wir die
signUp(username:delegate)
-Methode der Bibliothek, die asynchron reagiert, indem eine der Methoden für das übergebene Delegatobjekt aufgerufen wird, welches dasSignUpStartDelegate
-Protokoll implementieren muss. Die folgende Codezeile initiiert den Prozess für die Benutzerregistrierung:nativeAuth.signUp(username: email, delegate: self)
Wir übergeben in der
signUp(username:delegate)
-Methode die E-Mail-Adresse des Benutzers aus dem Übermittlungsformular und den Delegaten (eine Klasse, die dasSignUpStartDelegate
-Protokoll implementiert).Wenn Sie einen Benutzer per E-Mail-Adresse mit Kennwort registrieren möchten, verwenden Sie die folgenden Codeschnipsel:
@IBAction func signUpPressed(_: Any) { guard let email = emailTextField.text, let password = passwordTextField.text else { resultTextView.text = "Email or password not set" return } nativeAuth.signUp(username: email,password: password,delegate: self) }
Wir verwenden die
signUp(username:password:delegate)
-Methode der Bibliothek, die asynchron reagiert, indem eine der Methoden für das übergebene Delegatobjekt aufgerufen wird, das dasSignUpStartDelegate
-Protokoll implementieren muss. Die folgende Codezeile initiiert den Prozess für die Benutzerregistrierung:nativeAuth.signUp(username: email, password: password, delegate: self)
Wir übergeben in der
signUp(username:password:delegate)
-Methode die E-Mail-Adresse des Benutzers, das Kennwort und den Delegaten (eine Klasse, die dasSignUpStartDelegate
-Protokoll implementiert).Verwenden Sie folgenden Code, um das
SignUpStartDelegate
-Protokoll als Erweiterung für unsere Klasse zu implementieren:extension ViewController: SignUpStartDelegate { func onSignUpStartError(error: MSAL.SignUpStartError) { resultTextView.text = "Error signing up: \(error.errorDescription ?? "no description")" } func onSignUpCodeRequired( newState: MSAL.SignUpCodeRequiredState, sentTo: String, channelTargetType: MSAL.MSALNativeAuthChannelType, codeLength: Int ) { resultTextView.text = "Verification code sent to \(sentTo)" } }
Der Aufruf von
signUp(username:password:delegate)
odersignUp(username:delegate)
führt zu einem Aufruf der DelegatmethodeonSignUpCodeRequired()
oderonSignUpStartError()
.onSignUpCodeRequired(newState:sentTo:channelTargetType:codeLength)
wird aufgerufen, um anzugeben, dass ein Code gesendet wurde, um die Benutzer-E-Mail-Adresse zu überprüfen. Neben mit einigen Details darüber, von wo der Code gesendet wurde und wie viele Ziffern er enthält, verfügt diese Delegatmethode auch über einennewState
-Parameter vom TypSignUpCodeRequiredState
, der uns Zugriff auf zwei neue Methoden bietet:submitCode(code:delegate)
resendCode(delegate)
Um den vom Benutzer bereitgestellten Code zu übermitteln, verwenden Sie folgenden Code:
newState.submitCode(code: userSuppliedCode, delegate: self)
Verwenden Sie folgenden Code, um das
SignUpVerifyCodeDelegate
-Protokoll als Erweiterung für unsere Klasse zu implementieren:extension ViewController: SignUpVerifyCodeDelegate { func onSignUpVerifyCodeError(error: MSAL.VerifyCodeError, newState: MSAL.SignUpCodeRequiredState?) { resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")" } func onSignUpCompleted(newState: SignInAfterSignUpState) { resultTextView.text = "Signed up successfully!" } }
submitCode(code:delegate)
akzeptiert einen Delegatparameter, und wir müssen die erforderlichen Methoden im ProtokollSignUpVerifyCodeDelegate
implementieren. Im häufigsten Szenario erhalten wir einen Aufruf vononSignUpCompleted(newState)
, der angibt, dass die Benutzerregistrierung erfolgt und der Flow abgeschlossen ist.
Sammeln von Benutzerattributen während der Registrierung
Unabhängig davon, ob Sie einen Benutzer mit einem E-Mail-Einmal-Passcode oder mit Benutzername (E-Mail-Adresse) und Kennwort registrieren, können Sie Benutzerattribute erfassen, bevor das Konto eines Benutzers erstellt wird: Die signUp(username:attributes:delegate)
-Methode akzeptiert Attribute als Parameter.
Verwenden Sie zum Erfassen von Benutzerattributen den folgenden Codeschnipsel:
let attributes = [ "country": "United States", "city": "Redmond" ] nativeAuth.signUp(username: email, attributes: attributes, delegate: self)
signUp(username:attributes:delegate)
oderignUp(username:password:attributes:delegate)
führt zu einem Aufruf der DelegatmethodeonSignUpCodeRequired()
oderonSignUpStartError()
oder einen Aufruf vononSignUpAttributesInvalid(attributeNames: [String])
, wenn dies im Delegaten implementiert ist.Verwenden Sie den folgenden Codeschnipsel, um das Protokoll
SignUpStartDelegate
als Erweiterung für unsere Klasse zu implementieren:extension ViewController: SignUpStartDelegate { func onSignUpStartError(error: MSAL.SignUpStartError) { resultTextView.text = "Error signing up: \(error.errorDescription ?? "no description")" } func onSignUpCodeRequired( newState: MSAL.SignUpCodeRequiredState, sentTo: String, channelTargetType: MSAL.MSALNativeAuthChannelType, codeLength: Int ) { resultTextView.text = "Verification code sent to \(sentTo)" } func onSignUpAttributesInvalid(attributeNames: [String]) { resultTextView.text = "Invalid attributes \(attributeNames)" } }
Wenn die Attribute ungültig sind, wird die Methode
onSignUpAttributesInvalid(attributeNames: [String])
aufgerufen. In diesem Fall wird die Liste der ungültigen Attribute für den Benutzer angezeigt. Andernfalls wirdonSignUpCodeRequired(newState:sentTo:channelTargetType:codeLength)
aufgerufen, um anzugeben, dass ein Code gesendet wurde, um die E-Mail-Adresse des Benutzers zu überprüfen. Neben Details wie Codeempfänger und Anzahl der Ziffern des Codes verfügt diese Delegatmethode über einennewState
-Parameter vom TypSignUpCodeRequiredState
, der uns Zugriff auf zwei neue Methoden bietet:submitCode(code:delegate)
resendCode(delegate)
Benutzerattribute auf einer oder mehreren Seiten
Um die Attribute auf eine oder mehrere Seiten zu verteilen, müssen wir in der Konfiguration des CIAM-Mandanten (Customer Identity and Access Management, Kundenidentitäts- und Zugriffsverwaltung) die Attribute, die auf verschiedenen Seiten erfasst werden sollen, als obligatorisch festlegen.
Wir rufen signUp(username:password:delegate)
auf, ohne Attribute zu übergeben. Im nächsten Schritt wird newState.submitCode(code: userSuppliedCode, delegate: self)
aufgerufen, um die E-Mail-Adresse des Benutzers zu überprüfen.
Wir implementieren das SignUpVerifyCodeDelegate
-Protokoll als Erweiterung unserer Klasse wie zuvor, aber dieses Mal müssen wir die optionale Methode onSignUpAttributesRequired(attributes:newState)
zusätzlich zu den erforderlichen Methoden implementieren:
extension ViewController: SignUpVerifyCodeDelegate {
func onSignUpAttributesRequired(newState: SignUpAttributesRequiredState) {
resultTextView.text = "Attributes required"
}
func onSignUpVerifyCodeError(error: MSAL.VerifyCodeError, newState: MSAL.SignUpCodeRequiredState?) {
resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")"
}
func onSignUpCompleted(newState: SignInAfterSignUpState) {
resultTextView.text = "Signed up successfully!"
}
}
Diese Delegatmethode verfügt über einen newState
-Parameter vom Typ SignUpAttributesRequiredState
, der uns Zugriff auf eine neue Methode ermöglicht:
submitAttributes(attributes:delegate)
Verwenden Sie den folgenden Codeausschnitt, um die Attribute zu übermitteln, die der Benutzer bereitgestellt hat:
let attributes = [
"country": "United States",
"city": "Redmond"
]
newState.submitAttributes(attributes: attributes, delegate: self)
Außerdem implementieren wird das SignUpAttributesRequiredDelegate
-Protokoll als Erweiterung für unsere Klasse:
extension ViewController: SignUpAttributesRequiredDelegate {
func onSignUpAttributesRequiredError(error: AttributesRequiredError) {
resultTextView.text = "Error submitting attributes: \(error.errorDescription ?? "no description")"
}
func onSignUpAttributesRequired(attributes: [MSALNativeAuthRequiredAttribute], newState: SignUpAttributesRequiredState) {
resultTextView.text = "Attributes required"
}
func onSignUpAttributesInvalid(attributeNames: [String], newState: SignUpAttributesRequiredState) {
resultTextView.text = "Attributes invalid"
}
func onSignUpCompleted(newState: SignInAfterSignUpState) {
resultTextView.text = "Signed up successfully!"
}
}
Wenn der Benutzer nicht alle erforderlichen Attribute bereitstellt oder die Attribute ungültig sind, werden diese Delegatmethoden aufgerufen:
onSignUpAttributesInvalid
: Gibt an, dass bei mindestens einem gesendeten Attribut die Eingabeüberprüfung fehlgeschlagen ist. Dieser Fehler enthält einen attributNames-Parameter, bei dem es sich um eine Liste aller Attribute handelt, die vom Entwickler gesendet wurden und bei denen die Eingabeüberprüfung fehlgeschlagen ist.onSignUpAttributesRequired
: Gibt an, dass an den Server mindestens ein Attribut gesendet werden muss, bevor das Benutzerkonto erstellt werden kann. Dies geschieht, wenn mindestens ein Attribut in der Mandantenkonfiguration als obligatorisch festgelegt ist. Dieses Ergebnis enthält einen Attributparameter, bei dem es sich um eine Liste vonMSALNativeAuthRequiredAttribute
-Objekten handelt, die Details zu den von der API benötigten Benutzerattributen enthalten.
Beide Delegatmethoden enthalten einen Verweis auf den neuen Status. Wir verwenden den newState
-Parameter, um submitAttributes(attributes:delegate)
mit den neuen Attributen erneut aufzurufen.
Behandeln von Registrierungsfehlern
Bei der Registrierung ist nicht jede Aktion erfolgreich. Beispielsweise versucht der Benutzer möglicherweise, sich mit einer E-Mail-Adresse anzumelden, die bereits verwendet wird, oder einen ungültigen Code übermitteln.
In unserer früheren Implementierung des Protokolls SignUpStartDelegate
haben wir einfach den Fehler angezeigt, wenn wir die Delegatfunktion onSignUpStartError(error)
behandelt haben.
Verwenden Sie den folgenden Codeschnipsel, um die Benutzererfahrung zu verbessern, indem Sie den jeweiligen Fehlertyp verwalten:
func onSignUpStartError(error: MSAL.SignUpStartError) {
if error.isUserAlreadyExists {
resultTextView.text = "Unable to sign up: User already exists"
} else if error.isInvalidPassword {
resultTextView.text = "Unable to sign up: The password is invalid"
} else if error.isInvalidUsername {
resultTextView.text = "Unable to sign up: The username is invalid"
} else {
resultTextView.text = "Unexpected error signing up: \(error.errorDescription ?? "no description")"
}
}
Optional: Anmelden nach einem Registrierungsflow
Nach einem erfolgreichen Registrierungsflow können Sie einen Benutzer anmelden, ohne einen Anmeldeflow zu initiieren. Erfahren Sie mehr im Artikel Tutorial: Automatische Benutzeranmeldung nach der Registrierung in einer iOS/macOS App.