Udostępnij za pośrednictwem


Samouczek: dodawanie logowania i wylogowywanie w aplikacji dla systemu iOS/macOS przy użyciu uwierzytelniania natywnego

Dotyczy: Zielony okrąg z białym symbolem znacznika wyboru. iOS (Swift) macOS (Swift) Zielony okrąg z białym symbolem znacznika wyboru.

W tym samouczku pokazano, jak zalogować się i wylogować użytkownika przy użyciu jednorazowego kodu dostępu lub nazwy użytkownika lub hasła w aplikacji systemu iOS/macOS przy użyciu uwierzytelniania natywnego.

Z tego samouczka dowiesz się, jak wykonywać następujące czynności:

  • Zaloguj się do użytkownika przy użyciu jednorazowego kodu dostępu lub nazwy użytkownika (e-mail) i hasła.
  • Wyloguj użytkownika.
  • Błąd obsługi logowania

Wymagania wstępne

Logowanie użytkownika

Aby zalogować użytkownika przy użyciu jednorazowego przepływu kodu dostępu poczty e-mail, przechwyć wiadomość e-mail i wysłać wiadomość e-mail zawierającą jednorazowy kod dostępu użytkownika w celu zweryfikowania swojej poczty e-mail. Gdy użytkownik wprowadzi prawidłowy jednorazowy kod dostępu, aplikacja je zaloguje.

Aby zalogować użytkownika przy użyciu przepływu poczty e-mail z hasłem , przechwyć wiadomość e-mail i hasło. Jeśli nazwa użytkownika i hasło są prawidłowe, aplikacja loguje się do użytkownika.

Aby zalogować użytkownika, musisz:

  1. Utwórz interfejs użytkownika w celu:

    • Zbierz wiadomość e-mail od użytkownika. Dodaj walidację do danych wejściowych, aby upewnić się, że użytkownik wprowadzi prawidłowy adres e-mail.
    • Zbierz hasło, jeśli zalogujesz się przy użyciu nazwy użytkownika (e-mail) i hasła.
    • Zbierz jednorazowy kod dostępu wiadomości e-mail od użytkownika, jeśli logujesz się przy użyciu jednorazowego kodu dostępu poczty e-mail.
    • Dodaj przycisk, aby zezwolić użytkownikowi na ponowne wysłanie jednorazowego kodu dostępu, jeśli logujesz się przy użyciu jednorazowego kodu dostępu poczty e-mail.
  2. W interfejsie użytkownika dodaj przycisk, którego zdarzenie select uruchamia logowanie, jak pokazano w poniższym fragmencie kodu:

        @IBAction func signInPressed(_: Any) {
        guard let email = emailTextField.text else {
            resultTextView.text = "email not set"
            return
        }
    
        nativeAuth.signIn(username: email, delegate: self)
    }
    

    Aby zalogować użytkownika przy użyciu jednorazowego przepływu kodu dostępu e-mail, użyjemy następującego fragmentu kodu:

    nativeAuth.signIn(username: email, delegate: self)
    

    signIn(username:delegate) Metoda, która reaguje asynchronicznie, wywołując jedną z metod w przekazanym obiekcie delegataSignInStartDelegate, musi zaimplementować protokół. Przekazujemy adres e-mail podany przez użytkownika w formularzu przesyłania wiadomości e-mail i przekazujemy self go jako pełnomocnika.

    Aby zalogować użytkownika przy użyciu poczty e-mail z przepływem hasła , użyjemy następującego fragmentu kodu:

    nativeAuth.signIn(username: email, password: password, delegate: self)
    

    W metodzie signIn(username:password:delegate) należy przekazać adres e-mail dostarczony przez użytkownika, hasło i przekazać obiekt delegata zgodny z protokołem SignInStartDelegate . W tym przykładzie przekażemy selfwartość .

  3. Aby zaimplementować SignInStartDelegate protokół podczas korzystania z jednorazowego przepływu kodu dostępu poczty e-mail, użyj następującego fragmentu kodu:

    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)"
        }
    }
    

    Wyniki signIn(username:delegate) wywołania metody delegowania. W najbardziej typowym scenariuszu wywoływana jest nazwana w celu wskazania, onSignInCodeRequired(newState:sentTo:channelTargetType:codeLength) że kod został wysłany w celu zweryfikowania adresu e-mail użytkownika. Wraz ze szczegółowymi informacjami o tym, gdzie został wysłany kod i ile cyfr zawiera, ta metoda delegata ma newState również parametr typu SignInCodeRequiredState, który daje nam dostęp do następujących dwóch nowych metod:

    • submitCode(code:delegate)
    • resendCode(delegate)

    Użyj polecenia submitCode(code:delegate) , aby przesłać jednorazowy kod dostępu, który użytkownik dostarcza w formularzu jednorazowego kodu dostępu, użyj następującego fragmentu kodu:

    newState.submitCode(code: userSuppliedCode, delegate: self)
    

    Element submitCode(code:delegate) akceptuje jednorazowy kod dostępu i parametr delegata. Po przesłaniu kodu należy zweryfikować jednorazowy kod dostępu, implementując SignInVerifyCodeDelegate protokół.

    Aby zaimplementować SignInVerifyCodeDelegate protokół jako rozszerzenie klasy, użyj następującego fragmentu kodu:

    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)
        }
    }
    

    W najbardziej typowym scenariuszu otrzymujemy wywołanie onSignInCompleted(result) wskazujące, że użytkownik się zalogował. Wynik może służyć do pobrania .access token

    Element getAccessToken(delegate) akceptuje parametr delegata i musimy zaimplementować wymagane metody w protokole CredentialsDelegate .

    W najbardziej typowym scenariuszu otrzymujemy wywołanie onAccessTokenRetrieveCompleted(result) wskazujące, że użytkownik uzyskał access tokenelement .

    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. Aby zaimplementować SignInStartDelegate protokół podczas korzystania z poczty e-mail z przepływem haseł , użyj następującego fragmentu kodu:

    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
        }
    }
    

    W najbardziej typowym scenariuszu otrzymujemy wywołanie onSignInCompleted(result) wskazujące, że użytkownik się zalogował. Wynik może służyć do pobrania .access token

    Element getAccessToken(delegate) akceptuje parametr delegata i musimy zaimplementować wymagane metody w protokole CredentialsDelegate .

    W najbardziej typowym scenariuszu otrzymujemy wywołanie onAccessTokenRetrieveCompleted(result) wskazujące, że użytkownik uzyskał access tokenelement .

    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)"
        }
    }
    
    

Obsługa błędów logowania

Podczas logowania nie każda akcja kończy się powodzeniem. Na przykład użytkownik może spróbować zalogować się przy użyciu adresu e-mail, który nie istnieje lub przesłać nieprawidłowy kod.

  1. Aby obsłużyć błędy w metodzie signIn(username) lub signIn(username, password) , użyj następującego fragmentu kodu:

    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. Aby obsłużyć błędy w submitCode() metodzie, użyj następującego fragmentu kodu:

    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")"
        }
    }
    

    Jeśli użytkownik wprowadzi nieprawidłowy kod weryfikacyjny wiadomości e-mail, program obsługi błędów zawiera odwołanie do elementu SignInCodeRequiredState , którego można użyć do przesłania zaktualizowanego kodu. We wcześniejszej implementacji SignInVerifyCodeDelegate protokołu po prostu wyświetliliśmy błąd podczas obsługi funkcji delegata onSignInVerifyCodeError(error:newState) .

Oświadczenia tokenu identyfikatora odczytu

Gdy aplikacja uzyska token identyfikatora, możesz pobrać oświadczenia skojarzone z bieżącym kontem. W tym celu użyj następującego fragmentu kodu:

func onSignInCompleted(result: MSAL.MSALNativeAuthUserAccountResult) {
   let claims = result.account.accountClaims
   let preferredUsername = claims?["preferred_username"] as? String
}

Klucz używany do uzyskiwania dostępu do wartości oświadczenia to nazwa określona podczas dodawania atrybutu użytkownika jako oświadczenia tokenu.

Dowiedz się, jak dodawać wbudowane i niestandardowe atrybuty jako oświadczenia tokenu w artykule Dodawanie atrybutów użytkownika do oświadczeń tokenu .

Wyloguj użytkownika

Aby wylogować użytkownika, użyj odwołania do MSALNativeAuthUserAccountResult otrzymanego onSignInCompleted w wywołaniu zwrotnym lub użyj getNativeAuthUserAccount() polecenia , aby pobrać dowolne zalogowane konto z pamięci podręcznej i zapisać odwołanie w accountResult zmiennej składowej.

  1. Skonfiguruj grupę pęku kluczy dla projektu zgodnie z opisem w tym miejscu.

  2. Dodaj nową zmienną składową do ViewController klasy: var accountResult: MSALNativeAuthUserAccountResult?.

  3. Aktualizacja viewDidLoad w celu pobrania dowolnego buforowanego konta przez dodanie tego wiersza po nativeAuth pomyślnym zainicjowaniu: accountResult = nativeAuth.getNativeAuthUserAccount().

  4. Zaktualizuj program obsługi, signInCompleted aby zapisać wynik konta:

    func onSignInCompleted(result: MSALNativeAuthUserAccountResult) {
        resultTextView.text = "Signed in successfully"
    
        accountResult = result
    }
    
  5. Dodaj przycisk Wyloguj się i użyj następującego kodu, aby wylogować użytkownika:

    @IBAction func signOutPressed(_: Any) {
        guard let accountResult = accountResult else {
            print("Not currently signed in")
            return
        }
    
        accountResult.signOut()
    
        self.accountResult = nil
    
        resultTextView.text = "Signed out"
    }
    

Pomyślnie ukończono wszystkie kroki niezbędne do wylogowania użytkownika w aplikacji. Skompiluj i uruchom aplikację. Jeśli wszystko jest dobre, możesz wybrać przycisk wyloguj się, aby pomyślnie się wylogować.

Konfigurowanie niestandardowego dostawcy oświadczeń

Jeśli chcesz dodać oświadczenia z systemu zewnętrznego do tokenu wystawionego dla aplikacji, użyj niestandardowego dostawcy oświadczeń. Niestandardowy dostawca oświadczeń składa się z niestandardowego rozszerzenia uwierzytelniania, które wywołuje zewnętrzny interfejs API REST w celu pobierania oświadczeń z systemów zewnętrznych.

Wykonaj kroki opisane w temacie Konfigurowanie niestandardowego dostawcy oświadczeń, aby dodać oświadczenia z systemu zewnętrznego do tokenów zabezpieczających.