Freigeben über


Tutorial: An- und Abmeldung in 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 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

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:

  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 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.
  2. 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 das SignInStartDelegate-Protokoll implementieren. Wir übergeben die E-Mail-Adresse, die der/die Benutzer*in im E-Mail-Übermittlungsformular bereitstellt, und übergeben sie self 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 dem SignInStartDelegate-Protokoll entspricht. In diesem Beispiel übergeben wir self.

  3. 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 wird onSignInCodeRequired(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 einen newState Parameter vom Typ SignInCodeRequiredState, 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 das SignInVerifyCodeDelegate Protokoll implementieren.

    Verwenden Sie den folgenden Codeausschnitt, um dasSignInVerifyCodeDelegate 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 des access token verwendet werden.

    getAccessToken(delegate) akzeptiert einen Delegatparameter, und wir müssen die erforderlichen Methoden im Protokoll CredentialsDelegate implementieren.

    Im häufigsten Szenario erhalten wir einen Aufruf von onAccessTokenRetrieveCompleted(result), der angibt, dass der Benutzer ein access 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)"
        }
    }
    
    
  4. 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 des access token verwendet werden.

    getAccessToken(delegate) akzeptiert einen Delegatparameter, und wir müssen die erforderlichen Methoden im Protokoll CredentialsDelegate implementieren.

    Im häufigsten Szenario erhalten wir einen Aufruf von onAccessTokenRetrieveCompleted(result), der angibt, dass der Benutzer ein access 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.

  1. Verwenden Sie den folgenden Codeschnipsel, um Fehler bei der Methode signIn(username) oder signIn(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")"
        }
    }
    
  2. 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 des SignInVerifyCodeDelegate Protokolls haben wir einfach den Fehler angezeigt, wenn wir die onSignInVerifyCodeError(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.

  1. Konfigurieren Sie die Schlüsselbundgruppe für Ihr Projekt wie hier beschrieben.

  2. Fügen Sie ihrer ViewController Klassevar accountResult: MSALNativeAuthUserAccountResult? eine neue Membervariable hinzu:

  3. Aktualisieren Sie viewDidLoad, um alle zwischengespeicherten Konten abzurufen, indem Sie diese Zeile nach nativeAuth der Initialisierung erfolgreich hinzufügen: accountResult = nativeAuth.getNativeAuthUserAccount().

  4. Aktualisieren Sie den signInCompleted Handler, um das Kontoergebnis zu speichern:

    func onSignInCompleted(result: MSALNativeAuthUserAccountResult) {
        resultTextView.text = "Signed in successfully"
    
        accountResult = result
    }
    
  5. 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.