Tutorial: Adicionar entrada e saída no aplicativo iOS/macOS usando autenticação nativa
Aplica-se a: Locatários da força de trabalho
Inquilinos externos (saiba mais)
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, você aprenderá a:
- Inicie a sessão de um utilizador utilizando um código de acesso único por e-mail ou nome de utilizador (e-mail) e palavra-passe.
- Termine a sessão do utilizador.
- Tratar erro de início de sessão
Pré-requisitos
- Tutorial: Prepare seu aplicativo iOS/macOS para autenticação nativa.
- Se você quiser entrar usando Email com senha, configure seu fluxo de usuário para usar Email com senha quando você criar seu fluxo de usuário de inscrição e login.
Iniciar sessão do utilizador
Para iniciar sessão de um utilizador usando o fluxo de código de uso único do Email, capture o e-mail e envie um e-mail contendo um código de uso único para o utilizador verificar o seu e-mail. Quando o usuário insere uma senha única válida, o aplicativo faz login.
Para iniciar sessão de um utilizador utilizando o fluxo Email com palavra-passe, capture o e-mail e a palavra-passe. Se o nome de utilizador e a palavra-passe forem válidos, a aplicação inicia sessão no utilizador.
Para fazer login de um utilizador, tem de:
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.
- Recolha um código de uso único por e-mail do utilizador se iniciar sessão com um código de uso único por e-mail.
- Adicione um botão para permitir que o utilizador reenvie um código de acesso único se iniciar sessão com um código único por e-mail.
Na interface do utilizador, adicione um botão, cujo evento de seleção inicia um início de sessão, conforme mostrado no seguinte trecho de código:
@IBAction func signInPressed(_: Any) { guard let email = emailTextField.text else { resultTextView.text = "email not set" return } let parameters = MSALNativeAuthSignInParameters(username: email) nativeAuth.signIn(parameters: parameters, delegate: self) }
Para autenticar um utilizador usando o fluxo de código de uso único por e-mail , usamos o seguinte trecho de código:
nativeAuth.signIn(parameters: parameters, delegate: self)
O método
signIn(parameters:delegate)
, que responde de forma assíncrona chamando um dos métodos no objeto delegado passado, deve implementar o protocoloSignInStartDelegate
. Passamos uma instância deMSALNativeAuthSignInParameters
que contém o endereço de e-mail fornecido pelo utilizador no formulário de envio de e-mail, e definimosself
como delegado.Para entrar em um usuário usando Email com senha fluxo, usamos o seguinte trecho de código:
let parameters = MSALNativeAuthSignInParameters(username: email) parameters.password = password nativeAuth.signIn(parameters: parameters, delegate: self)
No método
signIn(parameters:delegate)
, você passa uma instância deMSALNativeAuthSignInParameters
que contém o endereço de e-mail que o usuário nos forneceu e sua senha, juntamente com o objeto delegado que está em conformidade com o protocoloSignInStartDelegate
. Para este exemplo, passamosself
.Para implementar o protocolo
SignInStartDelegate
quando você usa o fluxo de senha única de e-mail , 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)" } }
O
signIn(parameters:delegate)
resulta 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 parâmetronewState
do tipoSignInCodeRequiredState
, que nos dá acesso aos dois novos métodos a seguir: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 o código de acesso único e o parâmetro delegado. Depois de enviar o código, você deve verificar a senha única implementando o protocoloSignInVerifyCodeDelegate
.Para implementar
SignInVerifyCodeDelegate
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." let parameters = MSALNativeAuthGetAccessTokenParameters() result.getAccessToken(parameters: parameters, delegate: self) } }
No cenário mais comum, recebemos uma chamada para
onSignInCompleted(result)
indicando que o usuário entrou. O resultado pode ser usado para recuperar oaccess token
.O
getAccessToken(parameters:delegate)
aceita uma instânciaMSALNativeAuthGetAccessTokenParameters
e um parâmetro delegado, e devemos implementar os métodos necessários no protocoloCredentialsDelegate
.No cenário mais comum, recebemos uma chamada para
onAccessTokenRetrieveCompleted(result)
indicando que o usuário obteve umaccess token
.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)" } }
Para implementar o protocolo
SignInStartDelegate
ao utilizar o fluxo de senha com o 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 onSignInCompleted(result: MSAL.MSALNativeAuthUserAccountResult) { // User successfully signed in } }
No cenário mais comum, recebemos uma chamada para
onSignInCompleted(result)
indicando que o usuário entrou. O resultado pode ser usado para recuperar oaccess token
.O
getAccessToken(parameters:delegate)
aceita uma instânciaMSALNativeAuthGetAccessTokenParameters
e um parâmetro delegado, e devemos implementar os métodos necessários no protocoloCredentialsDelegate
.No cenário mais comum, recebemos uma chamada para
onAccessTokenRetrieveCompleted(result)
indicando que o usuário obteve umaccess token
.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)" } }
Lidar com erros de início de sessão
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.
Para manipular erros no método
signIn(parameters:delegate)
, 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")" } }
Para lidar com erros no método
submitCode()
, 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 deSignInVerifyCodeDelegate
protocolo, simplesmente exibimos o erro quando manipulamos a função de delegaçãoonSignInVerifyCodeError(error:newState)
.
Ler reivindicações do 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 que utiliza para aceder ao valor da declaração é o nome que especifica ao adicionar o atributo de utilizador 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.
Terminar sessão do utilizador
Para sair de um usuário, use a referência ao MSALNativeAuthUserAccountResult
que você recebeu no retorno de chamada onSignInCompleted
ou use getNativeAuthUserAccount()
para obter qualquer conta conectada do cache e armazenar uma referência na variável de membro accountResult
.
Configure o grupo de chaves para o seu projeto conforme descrito aqui.
Adicione uma nova variável de membro à sua classe
ViewController
:var accountResult: MSALNativeAuthUserAccountResult?
.Atualize
viewDidLoad
para recuperar qualquer conta em cache, adicionando esta linha depois quenativeAuth
foi inicializado com sucesso:accountResult = nativeAuth.getNativeAuthUserAccount()
.Atualize o manipulador de
signInCompleted
para armazenar o resultado da conta:func onSignInCompleted(result: MSALNativeAuthUserAccountResult) { resultTextView.text = "Signed in successfully" accountResult = result }
Adicione um botão Terminar Sessão e use o seguinte código para terminar a sessão do utilizador:
@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.