Udostępnij za pośrednictwem


Samouczek: samoobsługowe resetowanie hasła w aplikacji systemu iOS/macOS

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 zapewnić użytkownikom możliwość zmiany lub zresetowania hasła bez udziału administratora ani działu pomocy technicznej.

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

  • Dodaj samoobsługowe resetowanie hasła.
  • Obsługa błędów.

Wymagania wstępne

Resetowanie hasła

Aby zresetować hasło istniejącego użytkownika, musimy zweryfikować adres e-mail przy użyciu jednorazowego kodu dostępu (OTP).

  1. Aby zweryfikować wiadomość e-mail, wywołujemy metodę resetPassword(username:delegate) z wystąpienia zestawu SDK przy użyciu następującego fragmentu kodu:

    nativeAuth.resetPassword(username: email, delegate: self)
    
  2. Aby zaimplementować ResetPasswordStartDelegate protokół jako rozszerzenie klasy, użyj następującego fragmentu kodu:

    extension ViewController: ResetPasswordStartDelegate {
        func onResetPasswordCodeRequired(
            newState: MSAL.ResetPasswordCodeRequiredState,
            sentTo: String,
            channelTargetType: MSALNativeAuthChannelType,
            codeLength: Int
        ) {
            resultTextView.text = "Verification code sent to \(sentTo)"
        }
    
        func onResetPasswordStartError(error: MSAL.ResetPasswordStartError) {
            resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")"
        }
    }
    

    Wywołanie metody powoduje resetPassword(username:delegate) wywołanie onResetPasswordCodeRequired() metody lub onResetPasswordStartError() delegowania.

    W najbardziej typowym scenariuszu onResetPasswordCodeRequired(newState:sentTo:channelTargetType:codeLength) zostanie wywołany, aby wskazać, ż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 ResetPasswordCodeRequiredState, który daje nam dostęp do dwóch nowych metod:

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

    Aby przesłać kod dostarczony przez użytkownika, użyj:

    newState.submitCode(code: userSuppliedCode, delegate: self)
    
  3. Aby sprawdzić przesłany kod, zacznij od zaimplementowania ResetPasswordVerifyCodeDelegate protokołu jako rozszerzenia do klasy przy użyciu następującego fragmentu kodu:

    extension ViewController: ResetPasswordVerifyCodeDelegate {
    
        func onResetPasswordVerifyCodeError(
            error: MSAL.VerifyCodeError,
            newState: MSAL.ResetPasswordCodeRequiredState?
        ) {
            resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")"
        }
    
        func onPasswordRequired(newState: MSAL.ResetPasswordRequiredState) {
            // use newState instance to submit the new password
        }
    }
    

    W najbardziej typowym scenariuszu otrzymujemy wywołanie onPasswordRequired(newState) wskazujące, że możemy podać nowe hasło przy użyciu newState wystąpienia.

    newState.submitPassword(password: newPassword, delegate: self)
    
  4. Aby zaimplementować ResetPasswordRequiredDelegate protokół jako rozszerzenie klasy, użyj następującego fragmentu kodu:

    extension ViewController: ResetPasswordRequiredDelegate {
    
        func onResetPasswordRequiredError(
            error: MSAL.PasswordRequiredError,
            newState: MSAL.ResetPasswordRequiredState?
        ) {
            resultTextView.text = "Error submitting new password: \(error.errorDescription ?? "no description")"
        }
    
        func onResetPasswordCompleted(newState: SignInAfterResetPasswordState) {
            resultTextView.text = "Password reset completed"
        }
    }
    

    W najbardziej typowym scenariuszu otrzymujemy wywołanie onResetPasswordCompleted(newState) wskazujące, że przepływ resetowania hasła został ukończony.

Obsługa błędów

We wcześniejszej implementacji ResetPasswordStartDelegate protokołu wyświetliliśmy błąd, gdy obsłużyliśmy funkcję delegata onResetPasswordStartError(error) .

Możemy ulepszyć środowisko użytkownika, obsługując określony typ błędu w następujący sposób:

func onResetPasswordStartError(error: MSAL.ResetPasswordStartError) {
    if error.isInvalidUsername {
        resultTextView.text = "Invalid username"
    } else if error.isUserNotFound {
        resultTextView.text = "User not found"
    } else if error.isUserDoesNotHavePassword {
        resultTextView.text = "User is not registered with a password"
    } else {
        resultTextView.text = "Error during reset password flow in: \(error.errorDescription ?? "no description")"
    }
}

Obsługa błędów ze stanami

Niektóre błędy obejmują odwołanie do nowego stanu. Jeśli na przykład użytkownik wprowadzi nieprawidłowy kod weryfikacyjny wiadomości e-mail, program obsługi błędów zawiera odwołanie do elementu ResetPasswordCodeRequiredState , którego można użyć do przesłania nowego kodu weryfikacyjnego.

W poprzedniej implementacji ResetPasswordVerifyCodeDelegate protokołu po prostu wyświetliliśmy błąd podczas obsługi funkcji delegata onResetPasswordError(error:newState) .

Możemy ulepszyć środowisko użytkownika, prosząc użytkownika o wprowadzenie poprawnego kodu i ponowne przesłanie go w następujący sposób:

func onResetPasswordVerifyCodeError(
    error: MSAL.VerifyCodeError,
    newState: MSAL.ResetPasswordCodeRequiredState?
) {
    if error.isInvalidCode {
        // Inform the user that the submitted code was incorrect and ask for a new code to be supplied.
        // Request a new code calling `newState.resendCode(delegate)`
        let userSuppliedCode = retrieveNewCode(newState)
        newState?.submitCode(code: userSuppliedCode, delegate: self)
    } else {
        resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")"
    }
}

Innym przykładem, w którym program obsługi błędów zawiera odwołanie do nowego stanu, jest wprowadzenie przez użytkownika nieprawidłowego hasła. W takim przypadku program obsługi błędów zawiera odwołanie do elementu ResetPasswordRequiredState , którego można użyć do przesłania nowego hasła. Oto przykład:

func onResetPasswordRequiredError(
    error: MSAL.PasswordRequiredError,
    newState: MSAL.ResetPasswordRequiredState?
) {
    if error.isInvalidPassword {
        // Inform the user that the submitted password was invalid and ask for a new password to be supplied.
        let newPassword = retrieveNewPassword()
        newState?.submitPassword(password: newPassword, delegate: self)
    } else {
        resultTextView.text = "Error submitting password: \(error.errorDescription ?? "no description")"
    }
}

Zaloguj się po zresetowaniu hasła

Zestaw SDK zapewnia deweloperom możliwość logowania użytkownika po zresetowaniu hasła bez konieczności podawania nazwy użytkownika lub weryfikowania adresu e-mail za pomocą jednorazowego kodu dostępu.

Aby zalogować użytkownika po pomyślnym zresetowaniu hasła, użyj signIn(delegate) metody z nowego stanu SignInAfterResetPasswordState zwróconego onResetPasswordCompleted(newState) w funkcji:

extension ViewController: ResetPasswordRequiredDelegate {

    func onResetPasswordRequiredError(
        error: MSAL.PasswordRequiredError,
        newState: MSAL.ResetPasswordRequiredState?
    ) {
        resultTextView.text = "Error submitting new password: \(error.errorDescription ?? "no description")"
    }

    func onResetPasswordCompleted() {
        resultTextView.text = "Password reset completed"
        newState.signIn(delegate: self)
    }
}

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

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

extension ViewController: SignInAfterSignUpDelegate {
    func onSignInAfterSignUpError(error: SignInAfterSignUpError) {
        resultTextView.text = "Error signing in after password reset"
    }

    func onSignInCompleted(result: MSAL.MSALNativeAuthUserAccountResult) {
        // User successfully signed in
        result.getAccessToken(delegate: self)
    }
}

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

Następny krok