Freigeben über


Tutorial: Anmeldung in einer iOS/macOS App mit nativer Authentifizierung hinzufügen

Gilt für: Grüner Kreis mit weißem Häkchen. iOS (Swift) Grüner Kreis mit weißem Häkchen. 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

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:

  1. 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
  2. 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 das SignUpStartDelegate-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 das SignUpStartDelegate-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 das SignUpStartDelegate-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 das SignUpStartDelegate-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) oder signUp(username:delegate) führt zu einem Aufruf der Delegatmethode onSignUpCodeRequired() oder onSignUpStartError(). 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 einen newState-Parameter vom Typ SignUpCodeRequiredState, 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 Protokoll SignUpVerifyCodeDelegate implementieren. Im häufigsten Szenario erhalten wir einen Aufruf von onSignUpCompleted(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.

  1. 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) oder ignUp(username:password:attributes:delegate) führt zu einem Aufruf der Delegatmethode onSignUpCodeRequired() oder onSignUpStartError() oder einen Aufruf von onSignUpAttributesInvalid(attributeNames: [String]), wenn dies im Delegaten implementiert ist.

  2. 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 wird onSignUpCodeRequired(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 einen newState-Parameter vom Typ SignUpCodeRequiredState, 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 von MSALNativeAuthRequiredAttribute-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.

Nächster Schritt