Partilhar via


Tutorial: Redefinição de senha de autoatendimento no aplicativo iOS/macOS

Aplica-se a: Círculo verde com um símbolo de marca de verificação branco. iOS (Swift) Círculo verde com um símbolo de marca de verificação branco. macOS (Swift)

Este tutorial demonstra como dar aos usuários a capacidade de alterar ou redefinir sua senha, sem envolvimento de administrador ou suporte técnico.

Neste tutorial, irá aprender a:

  • Adicione a redefinição de senha de autoatendimento.
  • Manipule erros.

Pré-requisitos

Repor palavra-passe

Para redefinir a senha de um usuário existente, precisamos validar o endereço de e-mail usando uma OTP (one-time-passcode).

  1. Para validar o email, chamamos o resetPassword(username:delegate) método da instância do SDK usando o seguinte trecho de código:

    nativeAuth.resetPassword(username: email, delegate: self)
    
  2. Para implementar o ResetPasswordStartDelegate protocolo como uma extensão para nossa classe, use o seguinte trecho de código:

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

    A chamada para resetPassword(username:delegate) resulta em uma chamada para um ou onResetPasswordStartError() onResetPasswordCodeRequired() delegar métodos.

    No cenário onResetPasswordCodeRequired(newState:sentTo:channelTargetType:codeLength) mais comum será chamado para indicar que um código foi enviado para verificar o endereço de e-mail do usuário. Juntamente com alguns detalhes de onde o código foi enviado e quantos dígitos ele contém, este método delegado também tem um newState parâmetro de tipo ResetPasswordCodeRequiredState, que nos dá acesso a dois novos métodos:

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

    Para enviar o código que o usuário nos forneceu, use:

    newState.submitCode(code: userSuppliedCode, delegate: self)
    
  3. Para verificar o código enviado, comece implementando o ResetPasswordVerifyCodeDelegate protocolo como uma extensão para sua classe usando o seguinte trecho de código:

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

    No cenário mais comum, recebemos uma chamada para onPasswordRequired(newState) indicar que podemos fornecer a nova senha usando a newState instância.

    newState.submitPassword(password: newPassword, delegate: self)
    
  4. Para implementar o ResetPasswordRequiredDelegate protocolo como uma extensão para nossa classe, use o seguinte trecho de código:

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

    No cenário mais comum, recebemos uma chamada indicando onResetPasswordCompleted(newState) que o fluxo de redefinição de senha foi concluído.

Processar erros

Em nossa implementação anterior do ResetPasswordStartDelegate protocolo, exibimos o erro quando manipulamos a onResetPasswordStartError(error) função delegada.

Podemos melhorar a experiência do usuário lidando com o tipo de erro específico da seguinte maneira:

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

Manipular erros com estados

Alguns erros incluem uma referência a um novo estado. Por exemplo, se o usuário inserir um código de verificação de e-mail incorreto, o manipulador de erros incluirá uma referência a um ResetPasswordCodeRequiredState que pode ser usado para enviar um novo código de verificação.

Em nossa implementação anterior do ResetPasswordVerifyCodeDelegate protocolo, simplesmente exibimos o erro quando manipulamos a onResetPasswordError(error:newState) função de delegação.

Podemos melhorar a experiência do usuário pedindo ao usuário para inserir o código correto e reenviá-lo da seguinte maneira:

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

Outro exemplo em que o manipulador de erros inclui uma referência a um novo estado é quando o usuário insere uma senha inválida. Nesse caso, o manipulador de erros inclui uma referência a um ResetPasswordRequiredState que pode ser usado para enviar uma nova senha. Eis um exemplo:

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

Iniciar sessão após a reposição da palavra-passe

O SDK fornece aos desenvolvedores a capacidade de entrar em um usuário depois de redefinir sua senha sem precisar fornecer o nome de usuário ou verificar o endereço de e-mail por meio de uma senha única.

Para entrar em um usuário após a redefinição de senha bem-sucedida, use o signIn(delegate) método do novo estado SignInAfterResetPasswordState retornado na onResetPasswordCompleted(newState) função:

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

O signIn(delegate) aceita um parâmetro delegado e devemos implementar os métodos necessários no SignInAfterResetPasswordDelegate protocolo.

No cenário mais comum, recebemos uma chamada indicando onSignInCompleted(result) que o usuário entrou. O resultado pode ser usado para recuperar o access tokenarquivo .

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

O getAccessToken(delegate) aceita um parâmetro delegado e devemos implementar os métodos necessários no CredentialsDelegate protocolo.

No cenário mais comum, recebemos uma chamada indicando onAccessTokenRetrieveCompleted(result) que o usuário obteve um access tokenarquivo .

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

Próximo passo