Partilhar via


Tutorial: Adicionar entrada e saída no aplicativo iOS/macOS usando autenticação nativa

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 entrar e sair de um usuário com senha única de e-mail ou nome de usuário e senha em seu aplicativo iOS/macOS usando autenticação nativa.

Neste tutorial, irá aprender a:

  • Inicie sessão num utilizador utilizando um código de acesso ou nome de utilizador (e-mail) e palavra-passe por e-mail.
  • Saia de um usuário.
  • Manipular erro de entrada

Pré-requisitos

Utilizador de início de sessão

Para entrar em um usuário usando o fluxo de senha única de e-mail, capture o e-mail e envie um e-mail contendo uma senha única para o usuário verificar seu e-mail. Quando o usuário insere uma senha única válida, o aplicativo faz login.

Para entrar em um usuário usando o fluxo de e-mail com senha , capture o e-mail e a senha. Se o nome de utilizador e a palavra-passe forem válidos, a aplicação inicia sessão no utilizador.

Para iniciar sessão num utilizador, tem de:

  1. Crie uma interface do usuário (UI) para:

    • Colete um e-mail do usuário. Adicione validação às suas entradas para garantir que o usuário insira um endereço de e-mail válido.
    • Recolha uma palavra-passe se iniciar sessão com o nome de utilizador (e-mail) e a palavra-passe.
    • Colete uma senha única de e-mail do usuário se você entrar com uma senha única de e-mail.
    • Adicione um botão para permitir que o usuário reenvie uma senha única se você entrar com uma senha única por e-mail.
  2. Na interface do usuário, adicione um botão, cujo evento select inicia uma entrada, conforme mostrado no seguinte trecho de código:

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

    Para entrar em um usuário usando o fluxo de senha única de e-mail, usamos o seguinte trecho de código:

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

    O signIn(username:delegate) método, que responde de forma assíncrona chamando um dos métodos no objeto delegado passado, deve implementar o SignInStartDelegate protocolo. Passamos o endereço de e-mail que o usuário fornece no formulário de envio de e-mail e passamos self como delegado.

    Para entrar em um usuário usando o fluxo de e-mail com senha , usamos o seguinte trecho de código:

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

    signIn(username:password:delegate) No método, você passa o endereço de e-mail que o usuário nos forneceu, sua senha e passa o objeto delegado que está em conformidade com o SignInStartDelegate protocolo. Para este exemplo, passamos self.

  3. Para implementar SignInStartDelegate o protocolo ao usar o fluxo de senha única de email, use o seguinte trecho de código:

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

    Os signIn(username:delegate) resultados em uma chamada para delegar métodos. No cenário mais comum, onSignInCodeRequired(newState:sentTo:channelTargetType:codeLength) é 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 SignInCodeRequiredState, que nos dá acesso aos seguintes dois novos métodos:

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

    Use submitCode(code:delegate) para enviar a senha única que o usuário fornece no formulário de senha única, use o seguinte trecho de código:

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

    O submitCode(code:delegate) aceita a senha única e o parâmetro delegate. Depois de enviar o código, você deve verificar a senha única implementando o SignInVerifyCodeDelegate protocolo.

    Para implementar SignInVerifyCodeDelegate o protocolo como uma extensão para sua classe, use o seguinte trecho de código:

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

    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 .

    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)"
        }
    }
    
    
  4. Para implementar SignInStartDelegate o protocolo ao usar Email com fluxo de senha , use o seguinte trecho de código:

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

    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 .

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

Manipular erros de entrada

Durante o login, nem todas as ações são bem-sucedidas. Por exemplo, o usuário pode tentar entrar com um endereço de e-mail que não existe ou enviar um código inválido.

  1. Para manipular erros no signIn(username) método or signIn(username, password) , use o seguinte trecho de código:

    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. Para manipular erros no submitCode() método, use o seguinte trecho de código:

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

    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 SignInCodeRequiredState que pode ser usado para enviar um código atualizado. Em nossa implementação anterior do SignInVerifyCodeDelegate protocolo, simplesmente exibimos o erro quando manipulamos a onSignInVerifyCodeError(error:newState) função delegada.

Ler declarações de token de ID

Depois que seu aplicativo adquirir um token de ID, você poderá recuperar as declarações associadas à conta atual. Para fazer isso, use o seguinte trecho de código:

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

A chave usada para acessar o valor da declaração é o nome especificado ao adicionar o atributo user como uma declaração de token.

Saiba como adicionar atributos internos e personalizados como declarações de token no artigo Adicionar atributos de usuário a declarações de token.

Sair do usuário

Para sair de um usuário, use a referência ao MSALNativeAuthUserAccountResult que você recebeu no onSignInCompleted retorno de chamada ou use getNativeAuthUserAccount() para obter qualquer conta conectada do cache e armazenar uma referência na accountResult variável membro.

  1. Configure o grupo de chaves para o seu projeto, conforme descrito aqui.

  2. Adicione uma nova variável de membro à sua ViewController classe: var accountResult: MSALNativeAuthUserAccountResult?.

  3. Atualize viewDidLoad para recuperar qualquer conta armazenada em cache adicionando esta linha depois nativeAuth que for inicializada com êxito: accountResult = nativeAuth.getNativeAuthUserAccount().

  4. Atualize o signInCompleted manipulador para armazenar o resultado da conta:

    func onSignInCompleted(result: MSALNativeAuthUserAccountResult) {
        resultTextView.text = "Signed in successfully"
    
        accountResult = result
    }
    
  5. Adicione um botão Sair e use o seguinte código para sair do usuário:

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

Você concluiu com êxito todas as etapas necessárias para sair de um usuário em seu aplicativo. Crie e execute seu aplicativo. Se tudo estiver bem, você deve ser capaz de selecionar o botão de saída para sair com êxito.

Configurar provedor de declarações personalizado

Se você quiser adicionar declarações de um sistema externo ao token emitido para seu aplicativo, use um provedor de declarações personalizado. Um provedor de declarações personalizado é composto por uma extensão de autenticação personalizada que chama uma API REST externa para buscar declarações de sistemas externos.

Siga as etapas em Configurar um provedor de declarações personalizado para adicionar declarações de um sistema externo aos seus tokens de segurança.