Compartir vía


Tutorial: Adición de inicio de sesión en una aplicación de Android mediante la autenticación nativa

En este tutorial se muestra cómo iniciar sesión y cerrar sesión de un usuario con código de acceso de un solo uso por correo electrónico o nombre de usuario y contraseña en la aplicación móvil Android mediante la autenticación nativa.

En este tutorial, aprenderá a:

  • Inicie sesión en un usuario mediante el código de acceso de un solo uso de correo electrónico o el nombre de usuario (correo electrónico) y la contraseña.
  • Cierre de sesión de usuarios.
  • Control de errores de inicio de sesión

Requisitos previos

Inicio de sesión de un usuario

Para iniciar sesión un usuario mediante el código de acceso de un solo uso, recopile el correo electrónico y envíe un correo electrónico que contenga un código de acceso de un solo uso para que el usuario compruebe su correo electrónico. Cuando el usuario escribe un código de acceso de un solo uso válido, la aplicación hace que inicie sesión.

Para iniciar sesión en un usuario mediante el nombre de usuario (correo electrónico) y la contraseña, recopile el correo electrónico y la contraseña del usuario. Si el nombre de usuario y la contraseña son válidos, la aplicación inicia sesión en el usuario.

Para iniciar sesión en un usuario, debe hacer lo siguiente:

  1. Cree una interfaz de usuario (UI) para:

    • Recopilar un correo electrónico del usuario. Agregar validación a las entradas para asegurarse de que el usuario escribe una dirección de correo electrónico válida.
    • Recopilar una contraseña si inicia sesión con el nombre de usuario (correo electrónico) y la contraseña.
    • Recopile un código de acceso de un solo uso de correo electrónico del usuario si inicia sesión con el código de acceso de un solo uso por correo electrónico.
    • Vuelva a enviar el código de acceso de un solo uso (recomendado) si inicia sesión con el código de acceso de un solo uso por correo electrónico.
  2. En la interfaz de usuario, agregue un botón, cuyo evento select inicia un inicio de sesión como se muestra en el siguiente fragmento de código:

     CoroutineScope(Dispatchers.Main).launch {
         val actionResult = authClient.signIn(
             username = emailAddress
             //password = password, Pass 'password' param if you sign in with username (email) and password
         )
         if (actionResult is SignInResult.CodeRequired) {
             val nextState = actionResult.nextState
             val submitCodeActionResult = nextState.submitCode(
                 code = code
             )
             if (submitCodeActionResult is SignInResult.Complete){
                 // Handle sign in success
                 val accountState = submitCodeActionResult.resultValue
                 val accessTokenResult = accountState.getAccessToken()
                 if (accessTokenResult is GetAccessTokenResult.Complete) {
                     val accessToken = accessTokenResult.resultValue.accessToken
                     val idToken = accountState.getIdToken()
                 }
             }
         }
     }
    

    Si no es necesario que el usuario envíe un código de acceso, como cuando un usuario inicie sesión con correo electrónico y contraseña, use el siguiente fragmento de código:

        CoroutineScope(Dispatchers.Main).launch {
            val actionResult = authClient.signIn(
                username = emailAddress,
                password = password
            )
            if (actionResult is SignInResult.Complete) -> {
                // Handle sign in success
                val accountState = actionResult.resultValue
                val accessTokenResult = accountState.getAccessToken()
                if (accessTokenResult is GetAccessTokenResult.Complete) {
                        val accessToken = accessTokenResult.resultValue.accessToken
                        val idToken = accountState.getIdToken()
                    }
            }
        }
    
    • Para iniciar el flujo de inicio de sesión, use el método signIn(username) o signIn(username, password) del SDK.
    • El parámetro del método, username es la dirección de correo electrónico que recopila del usuario.
    • Si el método de inicio de sesión es nombre de usuario (correo electrónico) y contraseña, el parámetro del método, password es la contraseña que recopila del usuario.
    • En el escenario más común, el signIn(username) o signIn(username, password) devuelve un resultado, SignInResult.CodeRequired, que indica que el SDK espera que la aplicación envíe el código de acceso de un solo uso de correo electrónico enviado a la dirección de correo electrónico del usuario.
    • El objeto SignInResult.CodeRequired contiene una nueva referencia de estado, que podemos recuperar a través de actionResult.nextState.
    • El nuevo estado nos proporciona acceso a dos nuevos métodos:
      • submitCode() envía el código de acceso de un solo uso de correo electrónico que recopila la aplicación del usuario.
      • resendCode() vuelve a enviar el código de acceso de un solo uso por correo electrónico si el usuario no recibe el código.

Control de errores de inicio de sesión

Durante el inicio de sesión, no todas las acciones se realizan correctamente. Por ejemplo, el usuario podría intentar iniciar sesión con una dirección de correo electrónico que no existiera o enviar un código no válido.

Controlar los errores de inicio de sesión

Para controlar errores en el método signIn(username) o signIn(username, password), use el siguiente fragmento de código:

val actionResult = authClient.sign(
    username = emailAddress
    //password = password, Pass 'password' param if you sign in with username (email) and password
)
if (actionResult is SignInResult.CodeRequired) {
    // Next step: submit code
} else if (actionResult is SignInError) {
    // Handle sign in errors
    when {
         actionResult.isUserNotFound() -> {
             // Handle "user not found" error
         }
         actionResult.isAuthNotSupported() -> {
         // Handle "authentication type not support" error
         }
         actionResult.isInvalidCredentials() -> {
             // Handle specific errors
         }
         else -> {
             // Handle other errors
         }
     }
}
  • SignInError indica un resultado de acción incorrecto devuelto por signIn() y, por tanto, el resultado de la acción no incluye una referencia al nuevo estado.
  • Si actionResult is SignUpError, Android SDK proporciona métodos de utilidad para permitirle analizar aún más los errores específicos:
    • El método isUserNotFound() comprueba si el usuario inicia sesión con un nombre de usuario (dirección de correo electrónico) que no existe.
    • El método isBrowserRequired() comprueba la necesidad de un explorador (reserva web) para completar el flujo de autenticación. Este escenario se produce cuando la autenticación nativa no es suficiente para completar el flujo de autenticación. Por ejemplo, un administrador configura el correo electrónico y la contraseña como método de autenticación, pero la aplicación no puede enviar password como un tipo de desafío o simplemente no lo admite. Siga los pasos descritos en Reserva web de soporte técnico en la aplicación Android para controlar el escenario en el que se produce.
    • El método isAuthNotSupported() comprueba si la aplicación envía un tipo de desafío que Microsoft Entra no admite, es decir, un valor de tipo de desafío distinto de oob y contraseña. Obtenga más información sobre los tipos de desafío.
    • Para el nombre de usuario (correo electrónico) y el inicio de sesión con contraseña, el método isInvalidCredentials() comprueba si la combinación de nombre de usuario y contraseña es incorrecta.

Control de errores de código de envío

Para controlar errores en submitCode() método, use el siguiente fragmento de código:

val submitCodeActionResult = nextState.submitCode(
    code = code
)
if (submitCodeActionResult is SignInResult.Complete) {
    // Sign in flow complete, handle success state.
} else if (submitCodeActionResult is SubmitCodeError && submitCodeActionResult.isInvalidCode()) {
    // Handle "invalid code" error
}
  • El error SubmitCodeError indica un resultado de acción incorrecto devuelto por submitCode() y, por tanto, el resultado de la acción no incluye una referencia al nuevo estado.
  • El isInvalidCode() comprueba si hay un error específico. En este caso, se debe usar la referencia de estado anterior para volver a ejecutar la acción.

Para recuperar el nuevo código de acceso de un solo uso de correo electrónico, usa el siguiente fragmento de código:

val submitCodeActionResult = nextState.submitCode(
    code = code
)
if (submitCodeActionResult is SignInError && submitCodeActionResult.isInvalidCode) {
    // Inform the user that the submitted code was incorrect or invalid, then ask them to input a new email one-time passcode
    val newCode = retrieveNewCode()
    nextState.submitCode(
        code = newCode
    )
}

Has completado todos los pasos necesarios para conectar correctamente a usuarios en la aplicación. Compila y ejecuta tu aplicación. Si todo es correcto, deberías poder proporcionar un correo electrónico, recibir un código en el correo electrónico y usarlo para iniciar sesión correctamente al usuario.

Lectura de las notificaciones del token de identificador

Una vez que la aplicación adquiere un token de identificador, puedes recuperar las notificaciones asociadas a la cuenta actual. Para ello, usa el siguiente fragmento de código.

val preferredUsername = accountState.getClaims()?.get("preferred_username")
val city = accountState.getClaims()?.get("City")
val givenName = accountState.getClaims()?.get("given_name")
//custom attribute
val loyaltyNumber = accountState.getClaims()?.get("loyaltyNumber")

La clave que se usa para acceder al valor de notificación es el nombre que especificas al agregar el atributo de usuario como notificación de token.

Para obtener información sobre cómo agregar atributos integrados y personalizados a como notificaciones de token, consulta el artículo Adición de atributos de usuario a notificaciones de token.

Cierre de la sesión de un usuario

Para cerrar la sesión de un usuario, debes quitar la cuenta almacenada actualmente en la memoria caché.

  1. Crea la interfaz de usuario (UI) personalizada que incluya:

    • Un botón de cierre de sesión que el usuario selecciona para enviar una solicitud de cierre de sesión.
  2. Para cerrar la sesión de un usuario, usa el código siguiente:

    private fun performSignOut(accountState: AccountState) {
         CoroutineScope(Dispatchers.Main).launch {
            val accountResult = authClient.getCurrentAccount()
             if (accountResult is GetAccountResult.AccountFound) {
                 val signOutResult = accountResult.resultValue.signOut()
                 if (signOutResult is SignOutResult.Complete) {
                     // Show sign out successful UI
                 }
             }
         }
     }
    

Control de errores de cierre de sesión

El cierre de sesión no debería tener errores. Si se produjese algún error, inspecciona el resultado del error mediante el siguiente fragmento de código:

val actionResult = accountResult.signOut()
if (actionResult is SignOutResult.Complete) {
    // Show sign out successful UI
} else {
    // Handle errors
}

Asegúrate de incluir las instrucciones de importación. Android Studio debe incluir automáticamente las instrucciones de importación.

Has completado todos los pasos necesarios para cerrar la sesión de un usuario en la aplicación correctamente. Compila y ejecuta tu aplicación. Si todo es correcto, deberías poder seleccionar el botón cerrar sesión para cerrar la sesión correctamente.

Configuración del proveedor de notificaciones personalizado

Si quieres agregar notificaciones de un sistema externo al token emitido a la aplicación, usa un proveedor de notificaciones personalizado. Un proveedor de notificaciones personalizado se compone de una extensión de autenticación personalizada que llama a una API REST externa para obtener notificaciones de sistemas externos.

Sigue los pasos descritos en Configuración de un proveedor de notificaciones personalizado para agregar notificaciones desde un sistema externo a los tokens de seguridad.