Tutorial: Adicionar inscrição numa aplicação iOS/macOS usando autenticação nativa

Aplica-se a: círculo verde com um símbolo de marca de seleção branco que indica que o conteúdo a seguir se aplica a locatários externos. Inquilinos externos (saiba mais)

Este tutorial demonstra como registar um utilizador usando o código de acesso de email único ou nome de utilizador (email) e palavra-passe na sua aplicação iOS/macOS, utilizando autenticação nativa. Também aprende a recolher atributos de utilizador durante o registo, incluindo um nome de utilizador (alias), e a lidar com erros.

Neste tutorial, você:

  • Inscreva um usuário usando e-mail, senha única ou nome de usuário (e-mail) e senha.
  • Recolha atributos do utilizador durante o registo, incluindo um nome de utilizador (pseudónimo).
  • Lidar com erros de inscrição.

Pré-requisitos

Inscrever um utilizador

Para inscrever um utilizador usando o código de acesso único do email ou nome de utilizador (email) e palavra-passe, recolhe um email do utilizador e depois envia um email contendo um código de acesso único ao utilizador. O usuário insere uma senha única de e-mail válida para validar seu nome de usuário.

Para inscrever um usuário, você precisa:

  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.
    • Colete uma senha se você se inscrever com nome de usuário (e-mail) e senha.
    • Recolha um nome de utilizador (alias) se a sua aplicação suportar login baseado em alias.
    • Colete uma senha única de e-mail do usuário.
    • Se necessário, colete atributos de usuário.
    • Reenvie uma senha única se o usuário não a receber.
    • Inicie o fluxo de inscrição.
  2. Em seu aplicativo, adicione um botão, cujo evento select dispara o seguinte trecho de código:

    @IBAction func signUpPressed(_: Any) {
        guard let email = emailTextField.text else {
            resultTextView.text = "Email or password not set"
            return
        }
    
        let parameters = MSALNativeAuthSignUpParameters(username: email)
        nativeAuth.signUp(parameters: parameters, delegate: self)
    }
    
    • Para registar um utilizador usando o código de acesso único enviado por e-mail, use o método signUp(parameters:delegate) da biblioteca, que responde de forma assíncrona ao chamar um dos métodos no objeto delegado fornecido, que deve implementar o protocolo SignUpStartDelegate. A seguinte linha de código inicia o processo de inscrição do usuário:

      nativeAuth.signUp(parameters: parameters, delegate: self)
      

      No método signUp(parameters:delegate), passa uma instância de MSALNativeAuthSignUpParameters que contenha o endereço de e-mail do utilizador presente no formulário de submissão, juntamente com o delegado (uma classe que implementa o protocolo SignUpStartDelegate).

    • Para inscrever um usuário usando Email com senha, use os seguintes trechos de código:

      @IBAction func signUpPressed(_: Any) {
          guard let email = emailTextField.text, let password = passwordTextField.text else {
             resultTextView.text = "Email or password not set"
             return
          }
      
          let parameters = MSALNativeAuthSignUpParameters(username: email)
          parameters.password = password
          nativeAuth.signUp(parameters: parameters, delegate: self)
      }
      

      O método da biblioteca signUp(parameters:delegate) responde de forma assíncrona, chamando um dos métodos no objeto delegado fornecido, que deve implementar o protocolo SignUpStartDelegate. A seguinte linha de código inicia o processo de inscrição do usuário:

      nativeAuth.signUp(parameters: parameters, delegate: self)
      

      No signUp(parameters:delegate) método, passa uma MSALNativeAuthSignUpParameters instância contendo o endereço de email do utilizador e a sua palavra-passe juntamente com o delegado (uma classe que implementa o SignUpStartDelegate protocolo).

    • Para implementar o SignUpStartDelegate protocolo como uma extensão da sua classe, utilize:

      extension ViewController: SignUpStartDelegate {
          func onSignUpStartError(error: MSAL.SignUpStartError) {
              resultTextView.text = "Error signing up: \(error.errorDescription ?? "no description")"
          }
      
          func onSignUpCodeRequired(
              newState: MSAL.SignUpCodeRequiredState,
              sentTo: String,
              channelTargetType: MSAL.MSALNativeAuthChannelType,
              codeLength: Int
          ) {
              resultTextView.text = "Verification code sent to \(sentTo)"
          }
      }
      

      A chamada para signUp(parameters:delegate) resulta numa chamada para os métodos delegados onSignUpCodeRequired() ou onSignUpStartError(). O onSignUpCodeRequired(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 sobre onde o código foi enviado e quantos dígitos contém, este método de delegado também tem um newState parâmetro do tipo SignUpCodeRequiredState, que lhe dá acesso a dois novos métodos:

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

      Para submeter o código fornecido pelo utilizador, utilize:

      newState.submitCode(code: userSuppliedCode, delegate: self)
      
      • Para implementar o SignUpVerifyCodeDelegate protocolo como uma extensão da sua classe, utilize:

        extension ViewController: SignUpVerifyCodeDelegate {
            func onSignUpVerifyCodeError(error: MSAL.VerifyCodeError, newState: MSAL.SignUpCodeRequiredState?) {
                resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")"
            }
        
            func onSignUpCompleted(newState: SignInAfterSignUpState) {
                resultTextView.text = "Signed up successfully!"
            }
        }
        

        O submitCode(code:delegate) aceita um parâmetro de delegado e deve implementar os métodos necessários no protocolo SignUpVerifyCodeDelegate. No cenário mais comum, recebe uma chamada para onSignUpCompleted(newState), indicando que o utilizador foi registado e que o fluxo está concluído.

Coletar atributos de usuário durante a inscrição

Se você inscrever um usuário usando senha única de e-mail ou nome de usuário (e-mail) e senha, você pode coletar atributos de usuário antes que a conta de um usuário seja criada. O método signUp(parameters:delegate) pode ser chamado usando um MSALNativeAuthSignUpParameters que tem uma propriedade de atributos.

  1. Para coletar atributos de usuário, use o seguinte trecho de código:

    let attributes = [
        "country": "United States",
        "city": "Redmond"
    ]
    
    let parameters = MSALNativeAuthSignUpParameters(username: email)
    parameters.password = password
    parameters.attributes = attributes
    nativeAuth.signUp(parameters: parameters, delegate: self)
    

    O signUp(parameters:delegate)resulta numa chamada para os métodos do delegado onSignUpCodeRequired() ou onSignUpStartError(), ou numa chamada para onSignUpAttributesInvalid(attributeNames: [String]) se estiver implementado no delegado.

  2. Para implementar o SignUpStartDelegate protocolo como uma extensão da sua classe, use o seguinte excerto de código:

    extension ViewController: SignUpStartDelegate {
        func onSignUpStartError(error: MSAL.SignUpStartError) {
            resultTextView.text = "Error signing up: \(error.errorDescription ?? "no description")"
        }
    
        func onSignUpCodeRequired(
            newState: MSAL.SignUpCodeRequiredState,
            sentTo: String,
            channelTargetType: MSAL.MSALNativeAuthChannelType,
            codeLength: Int
        ) {
            resultTextView.text = "Verification code sent to \(sentTo)"
        }
    
        func onSignUpAttributesInvalid(attributeNames: [String]) {
           resultTextView.text = "Invalid attributes  \(attributeNames)"
        }
    }
    

    Se os atributos forem inválidos, o método onSignUpAttributesInvalid(attributeNames: [String]) será chamado. Neste caso, mostre a lista de atributos inválidos ao utilizador. Caso contrário, o onSignUpCodeRequired(newState:sentTo:channelTargetType:codeLength) é chamado para indicar que um código foi enviado para verificar o endereço de e-mail do usuário. Para além de detalhes como o destinatário do código e o número de dígitos do código, este método de delegado tem um newState parâmetro do tipo SignUpCodeRequiredState, que lhe dá acesso a dois novos métodos:

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

Atributos do usuário em uma ou mais páginas

Para distribuir os atributos por uma ou mais páginas, defina os atributos que pretende recolher em diferentes páginas como obrigatórios na configuração de Gestão de Identidade e Acesso do Cliente (CIAM).

Chamar signUp(parameters:delegate) sem passar quaisquer atributos na MSALNativeAuthSignUpParameters instância. O passo seguinte é ligar newState.submitCode(code: userSuppliedCode, delegate: self) para verificar o email do utilizador.

Implemente o SignUpVerifyCodeDelegate protocolo como uma extensão da sua classe como antes, mas desta vez deve implementar o método onSignUpAttributesRequired(attributes:newState) opcional além dos métodos exigidos:

extension ViewController: SignUpVerifyCodeDelegate {
    func onSignUpAttributesRequired(newState: SignUpAttributesRequiredState) {
        resultTextView.text = "Attributes required"
    }

    func onSignUpVerifyCodeError(error: MSAL.VerifyCodeError, newState: MSAL.SignUpCodeRequiredState?) {
        resultTextView.text = "Error verifying code: \(error.errorDescription ?? "no description")"
    }

    func onSignUpCompleted(newState: SignInAfterSignUpState) {
        resultTextView.text = "Signed up successfully!"
    }
}

Este método de delegado tem um newState parâmetro do tipo SignUpAttributesRequiredState, que lhe dá acesso a um novo método:

  • submitAttributes(attributes:delegate)

Para submeter os atributos fornecidos pelo utilizador, use o seguinte excerto de código:

let attributes = [
    "country": "United States",
    "city": "Redmond"
]

newState.submitAttributes(attributes: attributes, delegate: self)

Implementa também o protocolo SignUpAttributesRequiredDelegate como extensão da tua classe:

extension ViewController: SignUpAttributesRequiredDelegate {
    func onSignUpAttributesRequiredError(error: AttributesRequiredError) {
        resultTextView.text = "Error submitting attributes: \(error.errorDescription ?? "no description")"
    }

    func onSignUpAttributesRequired(attributes: [MSALNativeAuthRequiredAttribute], newState: SignUpAttributesRequiredState) {
        resultTextView.text = "Attributes required"
    }

    func onSignUpAttributesInvalid(attributeNames: [String], newState: SignUpAttributesRequiredState) {
        resultTextView.text = "Attributes invalid"
    }

    func onSignUpCompleted(newState: SignInAfterSignUpState) {
        resultTextView.text = "Signed up successfully!"
    }
}

Quando o usuário não fornece todos os atributos necessários, ou os atributos são inválidos, esses métodos delegados são chamados:

  • onSignUpAttributesInvalid: indica que um ou mais atributos enviados falharam na validação de entrada. Este erro contém um parâmetro attributeNames, que é uma lista de todos os atributos que foram enviados pelo desenvolvedor que falharam na validação de entrada.
  • onSignUpAttributesRequired: indica que o servidor requer que um ou mais atributos sejam enviados, antes que a conta de usuário possa ser criada. Isso acontece quando um ou mais atributos são definidos como obrigatórios na configuração do tenant. Esse resultado contém o parâmetro attributes, que é uma lista de objetos MSALNativeAuthRequiredAttribute, que descrevem detalhes sobre os atributos de usuário que a API exige.

Ambos os métodos delegados contêm uma nova referência de estado. Use o newState parâmetro para chamar submitAttributes(attributes:delegate) novamente com os novos atributos.

Recolha um nome de utilizador (alias) durante o registo

O nome de utilizador (alias) é um atributo especial do utilizador. Tal como outros atributos, como a cidade ou o país, recolhe essa informação durante o processo de registo. Ao contrário desses atributos, o utilizador pode depois usar o alias para iniciar sessão. O pseudónimo (por exemplo, "johndoe") oferece aos utilizadores uma forma mais curta e amigável de iniciar sessão do que o seu endereço de email.

O nome de utilizador (alias) não substitui o nome de utilizador (email). Durante o registo, a aplicação deve sempre recolher o nome de utilizador (email) como identificador principal, e recolhe o alias como um atributo juntamente com o email. No início de sessão, o utilizador pode então escolher iniciar sessão com o seu nome de utilizador (email) ou com o seu nome de utilizador (alias).

Quando o atributo de utilizador incorporado Username está ativado no seu fluxo de utilizador de inscrição, o SDK aceita-o através do mesmo dicionário de atributos utilizado para os outros atributos, com a chave flatusername. Podes passar o nome de utilizador (alias) diretamente na signUp chamada para que o utilizador não precise de passar por uma etapa separada exigida pelos atributos.

Para recolher um nome de utilizador (alias), adicione um campo de entrada para o nome de utilizador na sua interface de inscrição ao lado do campo de email, depois passe o alias como um atributo na chamada de inscrição:

guard let email = emailTextField.text, !email.isEmpty,
      let password = passwordTextField.text, !password.isEmpty,
      let username = usernameTextField.text, !username.isEmpty else {
    showResultText("Please fill in all fields")
    return
}

let attributes: [String: Any] = [
    "flatusername": username
]

let parameters = MSALNativeAuthSignUpParameters(username: email)
parameters.password = password
parameters.attributes = attributes
nativeAuth.signUp(parameters: parameters, delegate: self)

Para fluxos de código de acesso único de email (sem palavra-passe), passe os atributos sem definir palavra-passe:

let parameters = MSALNativeAuthSignUpParameters(username: email)
parameters.attributes = attributes
nativeAuth.signUp(parameters: parameters, delegate: self)

Ao lidar com erros de registo de nome de utilizador (alias), a error.isUserAlreadyExists propriedade também cobre um alias duplicado e error.isInvalidAttributes apresenta um valor de alias inválido.

Lidar com erros de inscrição

Durante a inscrição, nem todas as ações são bem-sucedidas. Por exemplo, o usuário pode tentar se inscrever com um endereço de e-mail que já está em uso ou enviar um código inválido.

Na implementação anterior do SignUpStartDelegate protocolo, o erro era simplesmente exibido ao manipular a onSignUpStartError(error) função de delegado.

Para melhorar a experiência do usuário gerenciando o tipo de erro específico, use o seguinte trecho de código:

func onSignUpStartError(error: MSAL.SignUpStartError) {
    if error.isUserAlreadyExists {
        resultTextView.text = "Unable to sign up: User already exists"
    } else if error.isInvalidPassword {
        resultTextView.text = "Unable to sign up: The password is invalid"
    } else if error.isInvalidUsername {
        resultTextView.text = "Unable to sign up: The username is invalid"
    } else {
        resultTextView.text = "Unexpected error signing up: \(error.errorDescription ?? "no description")"
    }
}

Opcional: Fazer login após o processo de inscrição

Após um fluxo de registo bem-sucedido, pode iniciar a sessão de um utilizador sem iniciar um fluxo de início de sessão. Se o utilizador se inscrever com um nome de utilizador (alias), pode iniciar sessão usando o seu endereço de email ou o seu alias. Saiba mais no artigo : Tutorial: Iniciar sessão automaticamente no utilizador após a inscrição em uma app iOS/macOS.

Próximo passo