Autenticación en wearables

Las apps para Wear OS pueden ejecutarse de manera independiente sin una aplicación complementaria. Esto significa que una app para Wear OS necesita administrar la autenticación por su cuenta cuando accede datos de Internet. Pero el tamaño pequeño de la pantalla del reloj limitan las opciones de autenticación que puede usar una app para Wear OS.

En esta guía, se tratan los métodos de autenticación que se recomienda usar en las apps para Wear OS y las alternativas disponibles si dichos métodos no se ajustan al caso práctico de una app.

Para obtener más información sobre cómo diseñar una buena experiencia de acceso, consulta la guía de UX de acceso.

Modo de Invitado

No se solicita autenticación para todas las funcionalidades. En su lugar, proporciona todas las funciones al usuario sin necesidad de que acceda.

Es posible que los usuarios descubran e instalen tu app para Wear sin haber usado el dispositivo móvil en la app, por lo que tal vez no tengan una cuenta ni sepan las funciones para todas las plataformas de Google. Asegúrate de que la funcionalidad del modo de invitado muestre con precisión las funciones de tu app.

Es posible que algunos dispositivos permanezcan desbloqueados más tiempo

En los dispositivos compatibles que ejecutan Wear OS 5 o versiones posteriores, el sistema detecta si el usuario lleva el dispositivo en la muñeca. Si el usuario desactiva la muñeca y se quita el dispositivo de la muñeca, el sistema mantiene desbloqueado durante un período más prolongado del que no lo haría de otra manera.

Si tu app requiere un nivel de seguridad más alto, como cuando se muestra datos potencialmente sensibles o privados, primero verifica si la detección de muñeca habilitado:

val wristDetectionEnabled =
        isWristDetectionAutoLockingEnabled(applicationContext)

Si el valor que se muestra de este método es false, pídele al usuario que acceda a un en tu app antes de mostrar contenido específico de usuario.

Métodos de autenticación recomendados

Usa los siguientes métodos de autenticación con el objetivo de habilitar apps independientes para Wear OS para lo siguiente: obtener credenciales de autenticación de usuarios.

Pasa tokens mediante la capa de datos

La app complementaria para teléfonos puede transferir datos de autenticación de forma segura a la app para Wear OS con la capa de datos de wearables. Transfiere credenciales como mensajes o elementos de datos.

Por lo general, este tipo de autenticación no requiere ninguna acción por parte del usuario. Sin embargo, evita realizar la autenticación sin informarle al usuario que está accediendo. Puedes hacer esto con una pantalla simple que se pueda descartar y que muestre que la cuenta se está transfiriendo desde un dispositivo móvil.

Importante: Tu app para Wear debe ofrecer al menos un método más de autenticación, ya que esta opción solo funciona en relojes vinculados con Android cuando está instalada la app para dispositivos móviles correspondiente. Proporciona un método de autenticación alternativo para los usuarios que no tengan la app para dispositivos móviles correspondiente o cuyos dispositivos Wear OS estén vinculados con un dispositivo iOS.

Pasa tokens con la capa de datos de la app para dispositivos móviles, como se muestra en el siguiente ejemplo:

val token = "..." // Auth token to transmit to the wearable device.
val dataClient: DataClient = Wearable.getDataClient(context)
val putDataReq: PutDataRequest = PutDataMapRequest.create("/auth").run {
    dataMap.putString("token", token)
    asPutDataRequest()
}
val putDataTask: Task<DataItem> = dataClient.putDataItem(putDataReq)

Detecta eventos de cambio de datos en la app de reloj, como se muestra en el siguiente ejemplo:

val dataClient: DataClient = Wearable.getDataClient(context)
dataClient.addListener{ dataEvents ->
    dataEvents.forEach { event ->
        if (event.type == DataEvent.TYPE_CHANGED) {
            val dataItemPath = event.dataItem.uri.path ?: ""
            if (dataItemPath.startsWith("/auth")) {
                val token = DataMapItem.fromDataItem(event.dataItem).dataMap.getString("token")
                // Display interstitial screen to notify the user they are being signed in.
                // Then, store the token and use it in network requests.
            }
        }
    }
}

Para obtener más información sobre el uso de la capa de datos de wearables, consulta Cómo enviar y sincronizar datos en Wear OS.

Usa OAuth 2.0

Wear OS admite dos flujos basados en OAuth 2.0, que se describen en las siguientes secciones:

  • Otorgamiento de código de autorización con clave de prueba para el intercambio de código (PKCE), como se define en RFC 7636
  • Otorgamiento de autorización de dispositivo, como se define en RFC 8628

Nota: Para ayudar a garantizar que tu app no se cierre cuando se active el modo ambiente en el reloj, habilita la opción "Siempre encendida" con AmbientModeSupport.attach en la actividad que realiza la autenticación. Para obtener más información sobre las prácticas recomendadas del modo ambiente, consulta Cómo mantener tu app visible en Wear.

Clave de prueba para el intercambio de código (PKCE)

Para usar la PKCE de manera efectiva, usa RemoteAuthClient.

A fin de realizar una solicitud de Auth a un proveedor de OAuth desde tu app para Wear OS, crea un objeto OAuthRequest. Este objeto consiste en una URL que dirige a tu extremo de OAuth para obtener un token y un objeto CodeChallenge. A continuación, te mostramos un código de ejemplo para crear una solicitud de Auth:

val request = OAuthRequest.Builder(this.applicationContext)
    .setAuthProviderUrl(Uri.parse("https://...."))
    .setClientId(clientId)
    .setCodeChallenge(codeChallenge)
    .build()

Una vez que compiles la solicitud de Auth, envíala a la app complementaria con el método sendAuthorizationRequest().

val client = RemoteAuthClient.create(this)
client.sendAuthorizationRequest(request,
    { command -> command?.run() },
    object : RemoteAuthClient.Callback() {
        override fun onAuthorizationResponse(
            request: OAuthRequest,
            response: OAuthResponse
        ) {
            // Extract the token from the response, store it and use it in network requests.
        }

        override fun onAuthorizationError(errorCode: Int) {
            // Handle error
        }
    }
)

Esta solicitud activará una llamada a la app complementaria, que luego presentará una IU de autorización en un navegador web en el teléfono celular del usuario. El proveedor de OAuth 2.0 autenticará al usuario y obtendrá su consentimiento para los permisos solicitados. La respuesta se envía a la URL de redireccionamiento que se genera automáticamente.

Luego de que la solicitud se procesa correctamente o falla, el servidor de OAuth 2.0 redirecciona a la URL especificada en la solicitud. Si el usuario aprueba la solicitud de acceso, la respuesta contendrá un código de autorización. Si no la aprueba, entonces esta contendrá un mensaje de error.

La respuesta lucirá como una cadena de consulta y se parecerá a uno de los ejemplos siguientes:

  https://wear.googleapis.com/3p_auth/com.your.package.name?code=xyz
  https://wear.googleapis-cn.com/3p_auth/com.your.package.name?code=xyz

Se cargará una página que dirigirá al usuario a la app complementaria, la cual verificará la URL de respuesta y la retransmitirá a la app de reloj de terceros con la API de onAuthorizationResponse.

Una vez hecho esto, la app de reloj podrá intercambiar el código de autorización por un token de acceso.

Nota: Una vez que se haya compilado el objeto OAuthRequest, podrás acceder a redirectUrl para dirigirte a la URL de redireccionamiento.

Otorgamiento de autorización de dispositivo

Cuando se usa el otorgamiento de autorización de dispositivo, el usuario abre el URI de verificación en otro dispositivo. Luego, el servidor de autorización les solicita aprobar o rechazar la solicitud.

Con el objetivo de facilitar este proceso, usa un RemoteActivityHelper para abrir una página web en el dispositivo móvil vinculado del usuario, como se muestra en el siguiente ejemplo:

// Request access from the authorization server and receive Device Authorization Response.
val verificationUri = "..." // Extracted from the Device Authorization Response.
RemoteActivityHelper.startRemoteActivity(
    this,
    Intent(Intent.ACTION_VIEW)
        .addCategory(Intent.CATEGORY_BROWSABLE)
        .setData(Uri.parse(verificationUri)),
    null
)
// Poll the authorization server to find out if the user completed the user authorization
// step on their mobile device.

Si tienes una app para iOS, usa vínculos universales e intercepta este intent en tu app, en lugar de depender del navegador para autorizar el token.

Otros métodos de autenticación

Wear OS admite otros métodos de acceso, que se describen en las siguientes secciones.

Acceso con Google

El Acceso con Google permite que el usuario acceda con su Cuenta de Google actual. Ofrece la del usuario ofrece una mejor experiencia y es fácil de mantener, especialmente si ya implementas en tus apps para dispositivos de mano.

Luego de los métodos de autenticación recomendados descritos anteriormente, Google El acceso es la siguiente solución preferida porque también funciona bien en iOS. Lo siguiente se describe cómo completar una integración básica de Acceso con Google.

Requisitos previos

Antes de comenzar a integrar el Acceso con Google en tu app para Wear OS, debes configurar una proyecto de la Consola de APIs de Google y configura tu proyecto de Android Studio. Para obtener más información, consulta Comienza a integrar el Acceso con Google en tu app para Android.

Si usas Acceso con Google en una app o sitio que se comunica con un servidor de backend, existen dos requisitos previos adicionales:

  • Crea un ID de cliente de aplicación web de OAuth 2.0 para tu servidor de backend. Este ID de cliente es diferente del ID de cliente de tu app. Para ver más información, consulta Cómo habilitar el acceso al servidor
  • Identifica al usuario que accedió de forma segura en el servidor enviando el token de ID del usuario. con HTTPS. Para saber cómo autenticar a tu usuario en el servidor de backend, consulta Autentica con un servidor de backend.

Integra el Acceso con Google en tu app

Revisa e implementa los siguientes pasos, que se detallan en las secciones. a fin de integrar el Acceso con Google en tu app para Wear OS:

  1. Configura el Acceso con Google.
  2. Agrega un botón de Acceso con Google.
  3. Inicia el flujo de acceso cuando el botón de acceso esté Presionado.

Configura el Acceso con Google y compila un objeto GoogleApiClient

En el método onCreate() de tu actividad de acceso, configura el Acceso con Google para solicitar los datos del usuario que requiere tu app. Luego, crea un objeto GoogleApiClient con a la API de Acceso con Google y a las opciones que especificaste. Estos pasos se muestran en el siguiente ejemplo:

public class MyNewActivity extends AppCompatActivity {

    private static final int RC_SIGN_IN = 9001;

    private GoogleSignInClient mSignInClient;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        GoogleSignInOptions options =
                new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                        .build();

        mSignInClient = GoogleSignIn.getClient(this, options);
    }
}

Agrega un botón de Acceso con Google a tu app

Para agregar un botón de Acceso con Google, completa los siguientes pasos:

  1. Agrega el SignInButton para el diseño de tu app:
  2.  <com.google.android.gms.common.SignInButton
     android:id="@+id/sign_in_button"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content" />
    
  3. En el método onCreate() de tu app, registra el botón OnClickListener para que el usuario acceda cuando lo presione:
  4. Kotlin

    findViewById<View>(R.id.sign_in_button).setOnClickListener(this)
    

    Java

    findViewById(R.id.sign_in_button).setOnClickListener(this);
    

Inicia el flujo de acceso y crea un intent de acceso

Controla las presiones del botón de acceso en tu onCLick() mediante la creación de un intent de acceso con el getSignInIntent(). Luego, inicia el intent con el startActivityForResult().

Intent intent = mSignInClient.getSignInIntent();
startActivityForResult(intent, RC_SIGN_IN);

Se le solicita al usuario que seleccione una Cuenta de Google para acceder. Si solicitaste permisos además del perfil, el correo electrónico y OpenID, también se le pide al usuario que otorgue acceso a esos de Google Cloud.

Por último, en la carpeta método onActivityResult, recupera el resultado de acceso con getSignInResultFromIntent Después de recuperar el resultado del acceso, puedes verifica si el acceso fue exitoso con el isSuccess. Si el acceso se realiza correctamente, puedes llamar al getSignInAccount para obtener un GoogleSignInAccount que contiene información sobre el usuario que accedió usuario, como su nombre. Estos pasos se muestran en el siguiente ejemplo:

Kotlin

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    super.onActivityResult(requestCode, resultCode, data)

    // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...).
    if (requestCode == RC_SIGN_IN) {
        Auth.GoogleSignInApi.getSignInResultFromIntent(data)?.apply {
            if (isSuccess) {
                // Get account information.
                fullName = signInAccount?.displayName
                mGivenName = signInAccount?.givenName
                mFamilyName = signInAccount?.familyName
                mEmail = signInAccount?.email
            }
        }
    }
}

Java

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...).
    if (requestCode == RC_SIGN_IN) {
        GoogleSignInResult signInResult = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        if (signInResult.isSuccess()) {
            GoogleSignInAccount acct = signInResult.getSignInAccount();

            // Get account information.
            fullName = acct.getDisplayName();
            givenName = acct.getGivenName();
            familyName = acct.getFamilyName();
            email = acct.getEmail();
        }
    }
}

Para ver una app de ejemplo que implementa Acceso con Google, consulta la Ejemplo de Acceso con Google de Horologist en GitHub.

Autenticación de código personalizada

Como alternativa a los métodos de autenticación descritos anteriormente, puedes puede requerir que el usuario se autentique desde otro dispositivo, como un teléfono celular o una tablet, y obtener un código numérico de corta duración. Luego, el usuario ingresa código en su dispositivo Wear OS para confirmar su identidad y recibir un token de Auth.

Este flujo de autenticación usa el módulo de acceso de tu app integra manualmente un método de acceso de un proveedor de Auth de terceros en el código de tu app. Aunque este método de autenticación requiere trabajo manual y un esfuerzo adicional para para que sea más segura, puedes usar este método si necesitas una autenticación previa en tus apps independientes para Wear OS.

El flujo de Auth para esta configuración funciona de la siguiente manera:

  1. El usuario realiza una acción con la app de Wear OS que requiere autorización.
  2. La app para Wear OS le presenta al usuario una pantalla de autenticación y le indica que el usuario ingrese un código desde una URL especificada.
  3. El usuario cambia a un dispositivo móvil, una tablet o una PC y, luego, inicia un navegador. navega a la URL especificada en la app para Wear OS y accede.
  4. El usuario recibe un código numérico de corta duración que debe ingresar en la app para Wear OS. Pantalla de autenticación con el teclado integrado en Wear OS:

  5. A partir de este momento, puedes usar el código ingresado como prueba de que este es el correcto. usuario e intercambiar el código por un token de Auth almacenado y protegido en un dispositivo Wear OS para las llamadas autenticadas que se desvían.

Nota: El código que genera el usuario debe ser solo numérico y no puede contener caracteres alfabéticos.

En el siguiente gráfico, se muestra el flujo de Auth: