OAuth 2.0 para aplicaciones de TV y dispositivos de entrada limitada

4

En este documento, se explica cómo implementar la autorización OAuth 2.0 para acceder a las API de Google a través de aplicaciones que se ejecutan en dispositivos como impresoras, consolas de juegos y impresoras. En particular, este flujo está diseñado para dispositivos que no tienen acceso a un navegador o que tienen capacidades de entrada limitadas.

OAuth 2.0 permite a los usuarios compartir datos específicos con una aplicación al mismo tiempo que mantienen privados sus nombres de usuario, contraseñas y otra información. Por ejemplo, una aplicación para TV puede usar OAuth 2.0 a fin de obtener permiso para seleccionar un archivo almacenado en Google Drive.

Como las aplicaciones que usan este flujo se distribuyen a dispositivos individuales, se supone que las apps no pueden conservar secretos. Pueden acceder a las API de Google mientras el usuario está presente en la app o se está ejecutando en segundo plano.

Alternativas

Si escribes una app para una plataforma como Android, iOS, macOS, Linux o Windows (incluida la plataforma universal de Windows), que tiene acceso al navegador y a todas las capacidades de entrada, usa el flujo de OAuth 2.0 para aplicaciones móviles y de escritorio. (Debes usar ese flujo incluso si tu app es una herramienta de línea de comandos sin una interfaz gráfica).

Si solo quieres que los usuarios accedan con sus Cuentas de Google y usas el token de ID JWT para obtener la información básica de perfil del usuario, consulta Acceso en TVs y dispositivos de entrada limitados.

Prerequisites

Habilita las API para tu proyecto.

Cualquier aplicación que llame a las API de Google debe habilitar esas API en el API Console.

Para habilitar una API en tu proyecto, sigue estos pasos:

  1. Open the API Library en Google API Console
  2. If prompted, select a project, or create a new one.
  3. API Library enumera todas las API disponibles, agrupadas por familia y popularidad del producto. Si la API que quieres habilitar no está visible en la lista, usa la búsqueda para encontrarla o haz clic en Ver todo en la familia de productos a la que pertenece.
  4. Seleccione la API que desea habilitar y, luego, haga clic en el botón Habilitar.
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

Crea credenciales de autorización

Todas las aplicaciones que usen OAuth 2.0 para acceder a las API de Google deben tener credenciales de autorización que identifiquen la aplicación al servidor de OAuth 2.0 de Google. En los siguientes pasos, se explica cómo crear credenciales para tu proyecto. Tus aplicaciones pueden usar las credenciales a fin de acceder a las API que hayas habilitado para ese proyecto.

  1. Go to the Credentials page.
  2. Haz clic en Crear credenciales > ID de cliente de OAuth.
  3. Selecciona el tipo de aplicación TVs and Limited Input Devices.
  4. Asigna un nombre a tu cliente de OAuth 2.0 y haz clic en Crear.

Identifica los permisos de acceso

Los permisos permiten que la aplicación solo solicite acceso a los recursos que necesita y, al mismo tiempo, permiten que los usuarios controlen la cantidad de acceso que otorgan a la aplicación. Por lo tanto, puede haber una relación inversa entre la cantidad de permisos solicitados y la probabilidad de obtener el consentimiento del usuario.

Antes de comenzar a implementar la autorización OAuth 2.0, te recomendamos que identifiques los permisos para los que tu app necesitará permiso de acceso.

Consulta la lista Alcances permitidos para conocer las apps o los dispositivos instalados.

Obtén tokens de acceso de OAuth 2.0

Aunque la aplicación se ejecute en un dispositivo con capacidades de entrada limitadas, los usuarios deben tener acceso separado a un dispositivo con capacidades de entrada enriquecidas para completar este flujo de autorización. El flujo tiene los siguientes pasos:

  1. La aplicación envía una solicitud al servidor de autorización de Google que identifica los permisos a los que la aplicación solicitará permiso para acceder.
  2. El servidor responde con varios datos utilizados en los pasos posteriores, como el código de un dispositivo y el código del usuario.
  3. Se muestra información que el usuario puede ingresar en otro dispositivo para autorizar tu app.
  4. Tu aplicación comienza a sondear el servidor de autorización de Google para determinar si el usuario autorizó tu aplicación.
  5. El usuario cambia a un dispositivo con capacidades de entrada enriquecidas, inicia un navegador web, navega a la URL que se muestra en el paso 3 e ingresa un código que también se muestra en el paso 3. El usuario puede otorgar (o rechazar) el acceso a tu aplicación.
  6. La siguiente respuesta a tu solicitud de sondeo contiene los tokens que tu app necesita para autorizar solicitudes en nombre del usuario. (Si el usuario rechazó el acceso a la aplicación, la respuesta no contiene tokens).

En la siguiente imagen, se ilustra este proceso:

El usuario accede en un dispositivo aparte que tiene un navegador.

En las siguientes secciones, se explican estos pasos en detalle. Debido a la variedad de capacidades y entornos de ejecución que pueden tener los dispositivos, en los ejemplos que se muestran en este documento, se usa la utilidad de línea de comandos curl. Estos ejemplos deben ser fáciles de portar a varios lenguajes y entornos de ejecución.

Paso 1: Solicita los códigos del usuario y del dispositivo

En este paso, el dispositivo envía una solicitud HTTP POST al servidor de autorización de Google, en https://oauth2.googleapis.com/device/code, que identifica tu aplicación y los permisos de acceso a los que quiere acceder la aplicación en nombre del usuario. Debes recuperar esta URL desde el Documento de descubrimiento mediante el valor de metadatos device_authorization_endpoint. Incluye los siguientes parámetros de solicitud HTTP:

Parámetros
client_id Obligatorio

El ID de cliente de tu aplicación. Puedes encontrar este valor en Credentials pagede API Console.

scope Obligatorio

Una lista delimitada por espacios de los permisos que identifican los recursos a los que podría acceder tu aplicación en nombre del usuario. Estos valores informan a la pantalla de consentimiento que Google muestra al usuario. Consulta la lista de Alcances permitidos para las apps o los dispositivos instalados.

Los permisos permiten que la aplicación solo solicite acceso a los recursos que necesita y, al mismo tiempo, permiten que los usuarios controlen la cantidad de acceso que otorgan a la aplicación. Por lo tanto, existe una relación inversa entre la cantidad de permisos solicitados y la probabilidad de obtener el consentimiento del usuario.

Examples

El siguiente fragmento muestra una solicitud de muestra:

POST /device/code HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

client_id=client_id&scope=

En este ejemplo, se muestra un comando curl para enviar la misma solicitud:

curl -d "client_id=client_id&scope=" \
     https://oauth2.googleapis.com/device/code

Paso 2: Controla la respuesta del servidor de autorización

El servidor de autorización mostrará una de las siguientes respuestas:

Respuesta correcta

Si la solicitud es válida, la respuesta será un objeto JSON que contiene las siguientes propiedades:

Propiedades
device_code Es un valor que Google asigna de forma única para identificar el dispositivo que ejecuta la app que solicita la autorización. El usuario autorizará ese dispositivo desde otro con capacidades de entrada más completas. Por ejemplo, un usuario puede usar una laptop o un teléfono celular para autorizar una app que se ejecuta en una TV. En este caso, el device_code identifica la TV.

Este código permite que el dispositivo que ejecuta la app determine de forma segura si el usuario otorgó o denegó el acceso.

expires_in El tiempo, en segundos, que son válidos device_code y user_code. Si, en ese momento, el usuario no completa el flujo de autorización y el dispositivo no sondea para recuperar información sobre la decisión del usuario, es posible que debas reiniciar este proceso del paso 1.
interval El tiempo en segundos que debe esperar el dispositivo entre solicitudes de sondeo. Por ejemplo, si el valor es 5, el dispositivo debe enviar una solicitud de sondeo al servidor de autorización de Google cada cinco segundos. Consulta el paso 3 para obtener más detalles.
user_code Un valor que distingue entre mayúsculas y minúsculas que identifica a Google los permisos a los que la aplicación solicita acceso. La interfaz de usuario le indicará al usuario que ingrese este valor en otro dispositivo con capacidades de entrada enriquecidas. Luego, Google usa el valor para mostrar el conjunto correcto de permisos cuando solicita al usuario que otorgue acceso a la aplicación.
verification_url Una URL a la que el usuario debe navegar en un dispositivo separado para ingresar el user_code y otorgar o denegar el acceso a tu aplicación. En la interfaz de usuario también se mostrará este valor.

En el siguiente fragmento, se muestra un ejemplo de respuesta:

{
  "device_code": "4/4-GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8",
  "user_code": "GQVQ-JKEC",
  "verification_url": "https://www.google.com/device",
  "expires_in": 1800,
  "interval": 5
}

Respuesta de la cuota excedida

Si las solicitudes de código de tu dispositivo superaron la cuota asociada con tu ID de cliente, recibirás una respuesta 403 con el siguiente error:

{
  "error_code": "rate_limit_exceeded"
}

En ese caso, utiliza una estrategia de retirada para reducir la tasa de solicitudes.

Paso 3: Muestra el código del usuario

Muestra al usuario el verification_url y el user_code que se obtuvieron en el paso 2. Ambos valores pueden contener cualquier carácter imprimible del grupo de caracteres US-ASCII. El contenido que le muestras al usuario debe indicar que navegue al verification_url en otro dispositivo y que ingrese el user_code.

Diseña tu interfaz de usuario (IU) con las siguientes reglas:

  • user_code
    • Se debe mostrar la user_code en un campo que admita caracteres de tamaño de 15 'W' En otras palabras, si puedes mostrar correctamente el código WWWWWWWWWWWWWWW, la IU es válida, y te recomendamos usar ese valor de string cuando pruebes la forma en que se muestra user_code en la IU.
    • user_code distingue mayúsculas de minúsculas y no se debe modificar de ninguna manera, como cambiar las mayúsculas o minúsculas o insertar otros caracteres de formato.
  • verification_url
    • El espacio en el que muestras el elemento verification_url debe ser lo suficientemente ancho como para admitir una string de URL de 40 caracteres.
    • No debes modificar la verification_url de ninguna manera, excepto para quitar el esquema de manera opcional. Si planeas quitar el esquema (p.ej., https://) de la URL por razones de visualización, asegúrate de que tu app pueda procesar las variantes http y https.

Paso 4: Consulta el servidor de autorización de Google

Dado que el usuario usará un dispositivo separado para navegar a verification_url y otorgará (o rechazará) el acceso al dispositivo solicitante, no se le notificará automáticamente cuando responda a la solicitud de acceso. Por esa razón, el dispositivo solicitante debe consultar el servidor de autorización de Google para determinar cuándo el usuario respondió a la solicitud.

El dispositivo solicitante debería seguir enviando solicitudes de sondeo hasta que reciba una respuesta que indique que el usuario respondió a la solicitud de acceso o hasta que los valores device_code y user_code que se obtuvieron en el paso 2 venzan. El interval que se muestra en el paso 2 especifica la cantidad de tiempo, en segundos, que se debe esperar entre las solicitudes.

La URL del extremo que se sondeará es https://oauth2.googleapis.com/token. La solicitud de sondeo contiene los siguientes parámetros:

Parámetros
client_id El ID de cliente de tu aplicación. Puedes encontrar este valor en Credentials pagede API Console.
client_secret El secreto de cliente del client_id proporcionado. Puedes encontrar este valor en Credentials pagede API Console.
device_code El device_code que muestra el servidor de autorización en el paso 2.
grant_type Configura este valor en urn:ietf:params:oauth:grant-type:device_code.

Examples

El siguiente fragmento muestra una solicitud de muestra:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

client_id=client_id&
client_secret=client_secret&
device_code=device_code&
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code

En este ejemplo, se muestra un comando curl para enviar la misma solicitud:

curl -d "client_id=client_id&client_secret=client_secret& \
         device_code=device_code& \
         grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Adevice_code" \
         -H "Content-Type: application/x-www-form-urlencoded" \
         /token

Paso 5: El usuario responde a la solicitud de acceso

En la siguiente imagen, se muestra una página similar a lo que los usuarios ven cuando navegan al verification_url que se mostró en el paso 3:

Conecta un dispositivo ingresando un código

Después de ingresar el objeto user_code y, si aún no lo hizo, acceder a Google, el usuario verá una pantalla de consentimiento como la que se muestra a continuación:

Ejemplo de pantalla de consentimiento para un cliente del dispositivo

Paso 6: Controla las respuestas a las solicitudes de sondeo

El servidor de autorización de Google responde a cada solicitud de sondeo con una de las siguientes respuestas:

Se otorgó el acceso

Si el usuario otorgó acceso al dispositivo (haciendo clic en Allow en la pantalla de consentimiento), la respuesta contendrá un token de acceso y un token de actualización. Los tokens permiten que tu dispositivo acceda a las API de Google en nombre del usuario. (La propiedad scope de la respuesta determina a qué API puede acceder el dispositivo).

En este caso, la respuesta de la API contiene los siguientes campos:

Campos
access_token El token que envía tu aplicación para autorizar una solicitud a la API de Google.
expires_in El ciclo de vida restante del token de acceso en segundos.
refresh_token Un token que puedes usar para obtener un nuevo token de acceso. Los tokens de actualización son válidos hasta que el usuario revoca el acceso. Ten en cuenta que siempre se muestran tokens de actualización para los dispositivos.
scope Los permisos de acceso otorgados por access_token, expresados como una lista de strings delimitadas por espacios y mayúsculas de minúsculas,
token_type El tipo de token que se muestra. En este momento, el valor de este campo siempre es Bearer.

En el siguiente fragmento, se muestra un ejemplo de respuesta:

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "scope": "openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email",
  "token_type": "Bearer",
  "refresh_token": "1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

Los tokens de acceso tienen una vida útil limitada. Si tu aplicación necesita acceder a una API durante un período prolongado, puede usar el token de actualización para obtener un token de acceso nuevo. Si tu aplicación necesita este tipo de acceso, debería almacenar el token de actualización para su uso posterior.

Acceso denegado

Si el usuario se niega a otorgar acceso al dispositivo, la respuesta del servidor tiene un código de estado de respuesta HTTP 403 (Forbidden). La respuesta contiene el siguiente error:

{
  "error": "access_denied",
  "error_description": "Forbidden"
}

Autorización pendiente

Si el usuario aún no completó el flujo de autorización, el servidor muestra un código de estado de respuesta HTTP 428 (Precondition Required). La respuesta contiene el siguiente error:

{
  "error": "authorization_pending",
  "error_description": "Precondition Required"
}

Sondeo con demasiada frecuencia

Si el dispositivo envía solicitudes de sondeo con demasiada frecuencia, el servidor muestra un código de estado de respuesta HTTP 403 (Forbidden). La respuesta contiene el siguiente error:

{
  "error": "slow_down",
  "error_description": "Forbidden"
}

Otros errores

El servidor de autorización también muestra errores si a la solicitud de sondeo le faltan algunos parámetros obligatorios o tiene un valor de parámetro incorrecto. Estas solicitudes suelen tener un código de estado HTTP 400 (Bad Request) o 401 (Unauthorized). Entre estos errores, se incluyen los siguientes:

Error Código de estado HTTP Descripción
invalid_client 401 No se encontró el cliente de OAuth. Por ejemplo, este error se produce si el valor del parámetro client_id no es válido.
invalid_grant 400 El valor del parámetro code no es válido.
unsupported_grant_type 400 El valor del parámetro grant_type no es válido.

Cómo llamar a las API de Google

Una vez que tu aplicación obtenga un token de acceso, puedes usarlo para hacer llamadas a una API de Google en nombre de una cuenta de usuario determinada si se otorgaron los permisos de acceso que requiere la API. Para ello, incluye el token de acceso en una solicitud a la API incluyendo un parámetro de búsqueda access_token o un valor Bearer de encabezado HTTP Authorization. Cuando es posible, se prefiere el encabezado HTTP, ya que las strings de consulta tienden a ser visibles en los registros del servidor. En la mayoría de los casos, puedes usar una biblioteca cliente para configurar tus llamadas a las API de Google (por ejemplo, al llamar a la API de Drive Files).

Puedes probar todas las API de Google y ver sus permisos en el Playground de OAuth 2.0.

Ejemplos de HTTP GET

Una llamada al extremo drive.files (la API de Drive Files) mediante el encabezado HTTP Authorization: Bearer podría verse de la siguiente manera. Ten en cuenta que debes especificar tu propio token de acceso:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

Esta es una llamada a la misma API para el usuario autenticado mediante el parámetro de string de consulta access_token:

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

curl ejemplos

Puedes probar estos comandos con la aplicación de línea de comandos de curl. A continuación, se muestra un ejemplo que usa la opción de encabezado HTTP (opción preferida):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

Como alternativa, puedes usar la opción del parámetro de string de consulta:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

Actualización de un token de acceso

Los tokens de acceso se vencen periódicamente y se convierten en credenciales no válidas para una solicitud a la API relacionada. Puedes actualizar un token de acceso sin solicitarle permiso al usuario (incluso cuando no está presente) si solicitaste acceso sin conexión a los permisos asociados con el token.

Para actualizar un token de acceso, la aplicación envía una solicitud POST de HTTPS al servidor de autorización de Google (https://oauth2.googleapis.com/token) que incluye los siguientes parámetros:

Campos
client_id Es el ID de cliente obtenido de API Console.
client_secret El secreto de cliente obtenido de API Console.
grant_type Como se define en la especificación de OAuth 2.0, el valor de este campo se debe establecer en refresh_token.
refresh_token El token de actualización que se muestra en el intercambio del código de autorización.

El siguiente fragmento muestra una solicitud de muestra:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

client_id=your_client_id&
client_secret=your_client_secret&
refresh_token=refresh_token&
grant_type=refresh_token

Siempre que el usuario no haya revocado el acceso otorgado a la aplicación, el servidor de tokens muestra un objeto JSON que contiene un token de acceso nuevo. En el siguiente fragmento, se muestra un ejemplo de respuesta:

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
  "token_type": "Bearer"
}

Ten en cuenta que hay límites en la cantidad de tokens de actualización que se emitirán: un límite por combinación cliente/usuario y otro por usuario para todos los clientes. Debes guardar los tokens de actualización en el almacenamiento a largo plazo y continuar usándolos mientras sean válidos. Si tu aplicación solicita demasiados tokens de actualización, es posible que se alcance a estos límites. En ese caso, los tokens de actualización más antiguos dejarán de funcionar.

Revoca un token

En algunos casos, un usuario podría querer revocar el acceso otorgado a una aplicación. Un usuario puede revocar el acceso desde la Configuración de la cuenta. Consulta la sección Cómo quitar el acceso a un sitio o app del documento de asistencia de sitios y apps de terceros con acceso a tu cuenta para obtener más información.

También es posible que una aplicación revoque de manera programática el acceso otorgado. La revocación programática es importante en los casos en los que un usuario anula la suscripción, quita una aplicación o los recursos de la API que requiere una aplicación cambiaron de manera significativa. En otras palabras, parte del proceso de eliminación puede incluir una solicitud a la API para garantizar que se quiten los permisos otorgados anteriormente a la aplicación.

Para revocar un token de manera programática, la aplicación realiza una solicitud a https://oauth2.googleapis.com/revoke e incluye el token como parámetro:

curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
        https://oauth2.googleapis.com/revoke?token={token}

El token puede ser un token de acceso o un token de actualización. Si el token es de acceso y tiene un token de actualización correspondiente, también se revocará el token de actualización.

Si la revocación se procesa correctamente, el código de estado HTTP de la respuesta es 200. Para las condiciones de error, se muestra un código de estado HTTP 400 junto con un código de error.

Permisos permitidos

El flujo de OAuth 2.0 para dispositivos solo se admite en los siguientes permisos:

OpenID Connect, Acceso con Google

  • email
  • openid
  • profile

API de Drive

  • https://www.googleapis.com/auth/drive.appdata
  • https://www.googleapis.com/auth/drive.file

API de YouTube

  • https://www.googleapis.com/auth/youtube
  • https://www.googleapis.com/auth/youtube.readonly