Tutorial: adicionar inscrição em um aplicativo iOS/macOS usando autenticação nativa
Aplica-se a: iOS (Swift) macOS (Swift)
Este tutorial demonstra como inscrever um usuário usando senha de uso único por email ou nome de usuário (email) e senha, e coletar atributos de usuário no seu aplicativo iOS/macOS usando autenticação nativa.
- Inscrever um usuário usando senha de uso único por email ou nome de usuário (email) e senha.
- Coletar atributos de usuário durante a inscrição.
- Identificar erros de inscrição.
Pré-requisitos
- Tutorial: preparar seu aplicativo iOS/macOS para a autenticação nativa.
- Se você quiser coletar atributos de usuário durante a inscrição, configure os atributos do usuário quando criar seu fluxo de usuário de inscrição e de entrada.
Inscrever um usuário
Para inscrever um usuário usando a senha de uso único por email ou o nome de usuário (email) e senha, você coleta um email do usuário e, em seguida, envia um email contendo uma senha de uso único por email para o usuário. O usuário insere uma senha de uso único por email válida para validar seu nome de usuário.
Para inscrever um usuário, você precisa:
Criar uma interface (IU) do usuário para:
- Coletar um email do usuário. Adicionar validação às suas entradas de dados para garantir que o usuário insira um endereço de email válido.
- Coletar uma senha se você se inscrever com o nome de usuário (email) e a senha.
- Coletar uma senha de uso único por email do usuário.
- Se necessário, coletar atributos de usuário.
- Reenvie a senha de uso único se não for recebida pelo usuário.
- Iniciar o fluxo de inscrição.
Em seu aplicativo, adicione um botão, cujo evento de seleção 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 } nativeAuth.signUp(username: email, delegate: self) }
Para inscrever o usuário usando Senha de uso único por email, usamos o método
signUp(username:delegate)
da biblioteca, que responde de forma assíncrona chamando um dos métodos no objeto delegado repassado, que precisa implementar o protocoloSignUpStartDelegate
. A seguinte linha de código inicia o processo de inscrição do usuário:nativeAuth.signUp(username: email, delegate: self)
No método
signUp(username:delegate)
, repassamos o endereço de email do usuário do formulário de envio e do delegado (uma classe que implementa o protocoloSignUpStartDelegate
).Para inscrever um usuário usando Email com senha, use os seguintes snippets 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 } nativeAuth.signUp(username: email,password: password,delegate: self) }
Usamos o método
signUp(username:password:delegate)
da biblioteca, que responde de maneira assíncrona chamando um dos métodos no objeto delegado repassado, que precisa implementar o protocoloSignUpStartDelegate
. A seguinte linha de código inicia o processo de inscrição do usuário:nativeAuth.signUp(username: email, password: password, delegate: self)
No método
signUp(username:password:delegate)
, repassamos o endereço de email do usuário, a respectiva senha e o delegado (uma classe que implementa o protocoloSignUpStartDelegate
).Para implementar o protocolo
SignUpStartDelegate
como uma extensão da classe, use: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 de
signUp(username:password:delegate)
ousignUp(username:delegate)
resulta em uma chamada dos métodos delegadosonSignUpCodeRequired()
ouonSignUpStartError()
. OonSignUpCodeRequired(newState:sentTo:channelTargetType:codeLength)
é chamado para indicar que um código foi enviado para verificar o endereço de email do usuário. Acompanhado de alguns detalhes, como local de envio do código e número de dígitos que ele contém, esse método delegado também tem um parâmetronewState
do tipoSignUpCodeRequiredState
, que fornece acesso a dois novos métodos:submitCode(code:delegate)
resendCode(delegate)
Para enviar o código fornecido pelo usuário, use:
newState.submitCode(code: userSuppliedCode, delegate: self)
Para implementar o protocolo
SignUpVerifyCodeDelegate
como uma extensão da classe, use: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 delegado e devemos implementar os métodos necessários no protocoloSignUpVerifyCodeDelegate
. No cenário mais comum, recebemos uma chamada deonSignUpCompleted(newState)
, indicando que o usuário se inscreveu e o fluxo foi concluído.
Coletar atributos de usuário durante a inscrição
Independentemente de você inscrever um usuário usando senha de uso único por email ou nome de usuário (email) e senha, você poderá coletar atributos de usuário antes que a conta de um usuário seja criada. O método signUp(username:attributes:delegate)
aceita atributos como um parâmetro.
Para coletar atributos de usuário, use o seguinte snippet de código:
let attributes = [ "country": "United States", "city": "Redmond" ] nativeAuth.signUp(username: email, attributes: attributes, delegate: self)
O
signUp(username:attributes:delegate)
ouignUp(username:password:attributes:delegate)
resultam em uma chamada dos métodos delegadosonSignUpCodeRequired()
ouonSignUpStartError()
, ou em uma chamada deonSignUpAttributesInvalid(attributeNames: [String])
se o método estiver implementado no delegado.Para implementar o protocolo
SignUpStartDelegate
como uma extensão da nossa classe, use o seguinte snippet 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. Nesse caso, a lista de atributos inválidos é exibida ao usuário. Caso contrário,onSignUpCodeRequired(newState:sentTo:channelTargetType:codeLength)
é chamado para indicar que um código foi enviado para verificar o endereço de email do usuário. Além de detalhes como o destinatário do código e o número de dígitos do código, esse método delegado tem um parâmetronewState
do tipoSignUpCodeRequiredState
, o que fornece acesso a dois novos métodos:submitCode(code:delegate)
resendCode(delegate)
Atributos de usuário em uma ou mais páginas
Para distribuir os atributos por uma ou mais páginas, precisamos definir os atributos que pretendemos coletar em páginas diferentes como obrigatórios na configuração do gerenciamento de acesso e identidade do cliente (CIAM) de um locatário.
Chamamos signUp(username:password:delegate)
sem repassar nenhum atributo. A próxima etapa será chamar newState.submitCode(code: userSuppliedCode, delegate: self)
para verificar o email do usuário.
Implementamos o protocolo SignUpVerifyCodeDelegate
como uma extensão da nossa classe como antes, mas desta vez precisamos implementar o método onSignUpAttributesRequired(attributes:newState)
opcional além dos métodos obrigatórios:
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!"
}
}
Esse método de delegado tem um parâmetro newState
do tipo SignUpAttributesRequiredState
, que nos dá acesso a um novo método:
submitAttributes(attributes:delegate)
Para enviar os atributos que o usuário nos forneceu, use o seguinte snippet de código:
let attributes = [
"country": "United States",
"city": "Redmond"
]
newState.submitAttributes(attributes: attributes, delegate: self)
Também vamos implementar o protocolo SignUpAttributesRequiredDelegate
como uma extensão da nossa 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 de delegado são chamados:
onSignUpAttributesInvalid
: indica que um ou mais atributos que foram enviados falharam na validação da entrada de dados. Esse erro contém um parâmetro attributeNames, que é uma lista de todos os atributos que foram enviados pelo desenvolvedor e falharam na validação de entrada.onSignUpAttributesRequired
: indica que o servidor requer que um ou mais atributos sejam enviados antes de a conta de usuário poder ser criada. Isso acontece quando um ou mais atributos são definidos como obrigatórios na configuração do locatário. Esse resultado contém o parâmetro de atributos, que é uma lista de objetosMSALNativeAuthRequiredAttribute
que descreve detalhes sobre os atributos de usuário requeridos pela API.
Ambos os métodos de delegado contêm uma referência ao novo estado. Vamos usar o parâmetro newState
para chamar submitAttributes(attributes:delegate)
novamente com os novos atributos.
Manipular 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 email que já está em uso ou enviar um código inválido.
Em nossa implementação anterior do protocolo SignUpStartDelegate
, simplesmente exibimos o erro quando tratamos a função delegada onSignUpStartError(error)
.
Para aprimorar 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: entrar após um fluxo de inscrição
Após um fluxo de inscrição bem-sucedido, você pode conectar um usuário sem iniciar um fluxo de entrada. Saiba mais no artigo Tutorial: conectar o usuário automaticamente após a inscrição em um aplicativo iOS/macOS.