Usar OAuth 2.0 para aplicaciones de servidor web

En este documento, se explica cómo las aplicaciones de servidor web usan las bibliotecas cliente de la API de Google o los extremos de Google OAuth 2.0 para implementar la autorización de OAuth 2.0 y acceder a las API de Google.

OAuth 2.0 permite a los usuarios compartir datos específicos con una aplicación y, al mismo tiempo, mantener la privacidad de sus nombres de usuario, contraseñas y demás información. Por ejemplo, una aplicación puede usar OAuth 2.0 a fin de obtener el permiso de los usuarios para almacenar archivos en sus unidades de Google Drive.

Este flujo de OAuth 2.0 es específicamente para la autorización del usuario. Está diseñada para aplicaciones que pueden almacenar información confidencial y mantener el estado. Una aplicación de servidor web debidamente autorizada puede acceder a una API mientras el usuario interactúa con la aplicación o después de que el usuario sale de ella.

Las aplicaciones de servidor web con frecuencia también usan cuentas de servicio para autorizar solicitudes a la API, en especial cuando se llama a las API de Cloud a fin de acceder a datos basados en proyectos en lugar de datos específicos del usuario. Las aplicaciones de servidor web pueden usar cuentas de servicio junto con la autorización del usuario.

Bibliotecas cliente

En los ejemplos específicos de cada lenguaje en esta página, se usan bibliotecas cliente de la API de Google para implementar la autorización OAuth 2.0. Para ejecutar las muestras de código, primero debes instalar la biblioteca cliente de tu lenguaje.

Cuando usas una biblioteca cliente de la API de Google para manejar el flujo de OAuth 2.0 de tu aplicación, la biblioteca cliente realiza muchas acciones que, de lo contrario, la aplicación debería realizar por su cuenta. Por ejemplo, determina cuándo la aplicación puede usar o actualizar los tokens de acceso almacenados, así como cuándo la aplicación debe volver a obtener el consentimiento. La biblioteca cliente también genera URLs de redireccionamiento correctas y ayuda a implementar controladores de redireccionamiento que intercambian códigos de autorización por tokens de acceso.

Las bibliotecas cliente de la API de Google para aplicaciones del servidor están disponibles para los siguientes lenguajes:

Requisitos previos

Habilita las API para tu proyecto.

Cualquier aplicación que llame a las APIs de Google debe habilitarlas en la API Console.

Para habilitar una API en tu proyecto, haz lo siguiente:

  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 APIs disponibles, agrupadas por familia de productos y popularidad. Si la API que quieres habilitar no está 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. Selecciona la API que deseas habilitar y, luego, haz 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

Cualquier aplicación que use OAuth 2.0 para acceder a las APIs de Google debe tener credenciales de autorización que identifiquen la aplicación para el servidor OAuth 2.0 de Google. En los siguientes pasos, se explica cómo crear credenciales para tu proyecto. Luego, tus aplicaciones pueden usar las credenciales con el objetivo de acceder a las APIs 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 Aplicación web.
  4. Completa el formulario y haz clic en Crear. Las aplicaciones que usan lenguajes y frameworks como PHP, Java, Python, Ruby y .NET deben especificar URI de redireccionamiento autorizados. Los URI de redireccionamiento son los extremos a los que el servidor de OAuth 2.0 puede enviar respuestas. Estos extremos deben cumplir con las reglas de validación de Google.

    Para las pruebas, puedes especificar URIs que hagan referencia a la máquina local, como http://localhost:8080. Con esto en mente, ten en cuenta que todos los ejemplos de este documento usan http://localhost:8080 como el URI de redireccionamiento.

    Te recomendamos que diseñes los extremos de autenticación de tu app para que esta no exponga códigos de autorización a otros recursos de la página.

Después de crear las credenciales, descarga el archivo client_secret.json del API Console. Almacena el archivo de forma segura en una ubicación a la que solo pueda acceder tu aplicación.

Identifica los permisos de acceso

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

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

También recomendamos que tu aplicación solicite acceso a los permisos de autorización mediante un proceso de autorización incremental, en el que tu aplicación solicita acceso a los datos del usuario en contexto. Esta práctica recomendada ayuda a los usuarios a comprender más fácilmente por qué tu aplicación necesita el acceso que solicita.

En el documento Alcances de la API de OAuth 2.0, se incluye una lista completa de los alcances que puedes usar para acceder a las API de Google.

Requisitos específicos para cada lenguaje

Para ejecutar cualquiera de las muestras de código de este documento, necesitarás una Cuenta de Google, acceso a Internet y un navegador web. Si usas una de las bibliotecas cliente de la API, también puedes consultar los requisitos específicos de cada lenguaje a continuación.

PHP

Para ejecutar las muestras de código de PHP en este documento, necesitarás lo siguiente:

  • PHP 5.6 o superior con la interfaz de línea de comandos (CLI) y la extensión JSON instalada
  • La herramienta de administración de dependencias de Composer
  • La biblioteca cliente de las APIs de Google para PHP:

    composer require google/apiclient:^2.10

Python

Para ejecutar las muestras de código de Python en este documento, necesitarás lo siguiente:

  • Python 2.6 o superior
  • La herramienta de administración de paquetes pip
  • La biblioteca cliente de las API de Google para Python:
    pip install --upgrade google-api-python-client
  • El google-auth, google-auth-oauthlib y google-auth-httplib2 para la autorización del usuario
    pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2
  • El framework de aplicaciones web de Flask en Python.
    pip install --upgrade flask
  • La biblioteca HTTP requests
    pip install --upgrade requests

Ruby

Para ejecutar las muestras de código de Ruby en este documento, necesitarás lo siguiente:

  • Ruby 2.6 o superior
  • La biblioteca de Google Auth para Ruby:

    gem install googleauth
  • El framework de aplicación web Ruby de Sinatra.

    gem install sinatra

Node.js

Para ejecutar las muestras de código de Node.js en este documento, necesitarás lo siguiente:

  • La LTS de mantenimiento, la LTS activa o la versión actual de Node.js.
  • El cliente Node.js de las API de Google realiza las siguientes acciones:

    npm install googleapis

HTTP/REST

No necesitas instalar ninguna biblioteca para poder llamar directamente a los extremos de OAuth 2.0.

Obtén tokens de acceso de OAuth 2.0

En los siguientes pasos, se muestra cómo interactúa tu aplicación con el servidor de OAuth 2.0 de Google a fin de obtener el consentimiento de un usuario para realizar una solicitud a la API en su nombre. Tu aplicación debe tener ese consentimiento para poder ejecutar una solicitud a la API de Google que requiera la autorización del usuario.

En la siguiente lista, se resumen rápidamente estos pasos:

  1. Tu aplicación identifica los permisos que necesita.
  2. Tu aplicación redirecciona al usuario a Google junto con la lista de permisos solicitados.
  3. El usuario decide si otorga los permisos a tu aplicación.
  4. Tu aplicación averigua lo que decidió el usuario.
  5. Si el usuario otorgó los permisos solicitados, tu aplicación recupera los tokens necesarios para realizar solicitudes a la API en nombre del usuario.

Paso 1: Configura los parámetros de autorización

El primer paso es crear la solicitud de autorización. Esa solicitud establece parámetros que identifican a tu aplicación y definen los permisos que se le pedirá al usuario que le otorgue a tu aplicación.

  • Si usas una biblioteca cliente de Google para la autenticación y autorización de OAuth 2.0, debes crear y configurar un objeto que defina estos parámetros.
  • Si llamas directamente al extremo de Google OAuth 2.0, generarás una URL y establecerás los parámetros en esa URL.

En las siguientes pestañas, se definen los parámetros de autorización admitidos para las aplicaciones de servidor web. En los ejemplos específicos de cada lenguaje, también se muestra cómo usar una biblioteca cliente o una biblioteca de autorización para configurar un objeto que establece esos parámetros.

PHP

El siguiente fragmento de código crea un objeto Google\Client(), que define los parámetros de la solicitud de autorización.

Ese objeto usa información de tu archivo client_secret.json para identificar tu aplicación. (Consulta cómo crear credenciales de autorización para obtener más información sobre ese archivo). El objeto también identifica los permisos a los que tu aplicación solicita permiso para acceder y la URL al extremo de autenticación de tu aplicación, que manejará la respuesta del servidor OAuth 2.0 de Google. Por último, el código establece los parámetros opcionales access_type y include_granted_scopes.

Por ejemplo, este código solicita acceso de solo lectura y sin conexión a la unidad de Google Drive de un usuario:

$client = new Google\Client();
$client->setAuthConfig('client_secret.json');
$client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY);
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
// offline access will give you both an access and refresh token so that
// your app can refresh the access token without user interaction.
$client->setAccessType('offline');
// Using "consent" will prompt the user for consent
$client->setPrompt('consent');
$client->setIncludeGrantedScopes(true);   // incremental auth

La solicitud especifica la siguiente información:

Parámetros
client_id Obligatorio

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

En PHP, llama a la función setAuthConfig para cargar las credenciales de autorización desde un archivo client_secret.json.

$client = new Google\Client();
$client->setAuthConfig('client_secret.json');
redirect_uri Obligatorio

Determina a dónde redirecciona el servidor de la API al usuario después de que este completa el flujo de autorización. El valor debe coincidir exactamente con uno de los URI de redireccionamiento autorizados para el cliente OAuth 2.0, que configuraste en la API Console Credentials pagede tu cliente. Si este valor no coincide con un URI de redireccionamiento autorizado para el client_id proporcionado, verás un error redirect_uri_mismatch.

Ten en cuenta que los esquemas http o https, las mayúsculas y la barra final (“/”) deben coincidir.

Para establecer este valor en PHP, llama a la función setRedirectUri. Ten en cuenta que debes especificar un URI de redireccionamiento válido para el client_id proporcionado.

$client->setRedirectUri('https://oauth2.example.com/code');
scope Obligatorio

Una lista delimitada por espacios de los permisos que identifican los recursos a los que tu aplicación podría acceder en nombre del usuario. Estos valores informan la pantalla de consentimiento que Google muestra al usuario.

Los permisos permiten que tu 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 tu aplicación. Por lo tanto, existe una relación inversa entre la cantidad de alcances solicitados y la probabilidad de obtener el consentimiento del usuario.

Para configurar este valor en PHP, llama a la función addScope:

$client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY);

Recomendamos que tu aplicación solicite acceso a los permisos de autorización en contexto siempre que sea posible. Si solicitas acceso a los datos del usuario en contexto, mediante la autorización incremental, ayudas a los usuarios a comprender más fácilmente por qué tu aplicación necesita el acceso que solicita.

access_type Se recomienda

Indica si tu aplicación puede actualizar los tokens de acceso cuando el usuario no está presente en el navegador. Los valores de parámetro válidos son online, que es el valor predeterminado, y offline.

Establece el valor en offline si tu aplicación necesita actualizar los tokens de acceso cuando el usuario no está presente en el navegador. Este es el método para actualizar los tokens de acceso que se describe más adelante en este documento. Este valor le indica al servidor de autorización de Google que muestre un token de actualización y un token de acceso la primera vez que tu aplicación intercambia un código de autorización por tokens.

Para configurar este valor en PHP, llama a la función setAccessType:

$client->setAccessType('offline');
state Se recomienda

Especifica cualquier valor de string que tu aplicación usa para mantener el estado entre la solicitud de autorización y la respuesta del servidor de autorización. El servidor muestra el valor exacto que envías como un par name=value en el componente de consulta de URL (?) de redirect_uri después de que el usuario otorga su consentimiento o rechaza la solicitud de acceso de tu aplicación.

Puedes usar este parámetro para varios fines, como dirigir al usuario al recurso correcto en tu aplicación, enviar nonces y mitigar la falsificación de solicitudes entre sitios. Como tu redirect_uri puede adivinarse, usar un valor state puede aumentar la seguridad de que una conexión entrante sea el resultado de una solicitud de autenticación. Si generas una string aleatoria o codificas el hash de una cookie o algún otro valor que captura el estado del cliente, puedes validar la respuesta para garantizar, además, que la solicitud y la respuesta se hayan originado en el mismo navegador, lo que brinda protección contra ataques como la falsificación de solicitudes entre sitios. Consulta la documentación de OpenID Connect para ver un ejemplo de cómo crear y confirmar un token state.

Para configurar este valor en PHP, llama a la función setState:

$client->setState($sample_passthrough_value);
include_granted_scopes Opcional

Permite que las aplicaciones usen la autorización incremental para solicitar acceso a permisos adicionales en contexto. Si configuras el valor de este parámetro en true y se otorga la solicitud de autorización, el nuevo token de acceso también cubrirá los permisos a los que el usuario otorgó acceso a la aplicación con anterioridad. Consulta la sección de autorización incremental para ver ejemplos.

Para configurar este valor en PHP, llama a la función setIncludeGrantedScopes:

$client->setIncludeGrantedScopes(true);
login_hint Opcional

Si tu aplicación sabe qué usuario está intentando autenticar, puede usar este parámetro para proporcionar una sugerencia al servidor de autenticación de Google. El servidor usa la sugerencia para simplificar el flujo de acceso, ya sea completando previamente el campo de correo electrónico en el formulario de acceso o seleccionando la sesión de acceso múltiple adecuada.

Establece el valor del parámetro en una dirección de correo electrónico o un identificador sub, que equivale al ID de Google del usuario.

Para configurar este valor en PHP, llama a la función setLoginHint:

$client->setLoginHint('None');
prompt Opcional

Una lista de mensajes para presentar al usuario, delimitados por espacios y que distinguen mayúsculas de minúsculas Si no especificas este parámetro, se le pedirá al usuario solo la primera vez que tu proyecto solicite acceso. Para obtener más información, consulta Cómo solicitar que se vuelva a dar consentimiento.

Para configurar este valor en PHP, llama a la función setPrompt:

$client->setPrompt('consent');

Los valores posibles son:

none No muestres ninguna pantalla de autenticación ni de consentimiento. No se debe especificar con otros valores.
consent Solicita el consentimiento del usuario.
select_account Solicítale al usuario que seleccione una cuenta.

Python

En el siguiente fragmento de código, se usa el módulo google-auth-oauthlib.flow para crear la solicitud de autorización.

El código construye un objeto Flow, que identifica tu aplicación con la información del archivo client_secret.json que descargaste después de crear credenciales de autorización. Ese objeto también identifica los permisos a los que tu aplicación solicita permiso para acceder y la URL al extremo de autenticación de tu aplicación, que manejará la respuesta del servidor OAuth 2.0 de Google. Por último, el código establece los parámetros opcionales access_type y include_granted_scopes.

Por ejemplo, este código solicita acceso de solo lectura y sin conexión a la unidad de Google Drive de un usuario:

import google.oauth2.credentials
import google_auth_oauthlib.flow

# Use the client_secret.json file to identify the application requesting
# authorization. The client ID (from that file) and access scopes are required.
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'])

# Indicate where the API server will redirect the user after the user completes
# the authorization flow. The redirect URI is required. The value must exactly
# match one of the authorized redirect URIs for the OAuth 2.0 client, which you
# configured in the API Console. If this value doesn't match an authorized URI,
# you will get a 'redirect_uri_mismatch' error.
flow.redirect_uri = 'https://www.example.com/oauth2callback'

# Generate URL for request to Google's OAuth 2.0 server.
# Use kwargs to set optional request parameters.
authorization_url, state = flow.authorization_url(
    # Enable offline access so that you can refresh an access token without
    # re-prompting the user for permission. Recommended for web server apps.
    access_type='offline',
    # Enable incremental authorization. Recommended as a best practice.
    include_granted_scopes='true')

La solicitud especifica la siguiente información:

Parámetros
client_id Obligatorio

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

En Python, llama al método from_client_secrets_file para recuperar el ID de cliente desde un archivo client_secret.json. También puedes usar el método from_client_config, que pasa la configuración del cliente como apareció originalmente en un archivo de secretos del cliente, pero no accede al archivo en sí.

flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'])
redirect_uri Obligatorio

Determina a dónde redirecciona el servidor de la API al usuario después de que este completa el flujo de autorización. El valor debe coincidir exactamente con uno de los URI de redireccionamiento autorizados para el cliente OAuth 2.0, que configuraste en la API Console Credentials pagede tu cliente. Si este valor no coincide con un URI de redireccionamiento autorizado para el client_id proporcionado, verás un error redirect_uri_mismatch.

Ten en cuenta que los esquemas http o https, las mayúsculas y la barra final (“/”) deben coincidir.

Para establecer este valor en Python, configura la propiedad redirect_uri del objeto flow:

flow.redirect_uri = 'https://oauth2.example.com/code'
scope Obligatorio

Una lista de alcances que identifican los recursos a los que tu aplicación podría acceder en nombre del usuario. Estos valores informan la pantalla de consentimiento que Google muestra al usuario.

Los permisos permiten que tu 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 tu aplicación. Por lo tanto, existe una relación inversa entre la cantidad de alcances solicitados y la probabilidad de obtener el consentimiento del usuario.

En Python, usa el mismo método que usas para configurar client_id a fin de especificar la lista de permisos.

flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'])

Recomendamos que tu aplicación solicite acceso a los permisos de autorización en contexto siempre que sea posible. Si solicitas acceso a los datos del usuario en contexto, mediante la autorización incremental, ayudas a los usuarios a comprender más fácilmente por qué tu aplicación necesita el acceso que solicita.

access_type Se recomienda

Indica si tu aplicación puede actualizar los tokens de acceso cuando el usuario no está presente en el navegador. Los valores de parámetro válidos son online, que es el valor predeterminado, y offline.

Establece el valor en offline si tu aplicación necesita actualizar los tokens de acceso cuando el usuario no está presente en el navegador. Este es el método para actualizar los tokens de acceso que se describe más adelante en este documento. Este valor le indica al servidor de autorización de Google que muestre un token de actualización y un token de acceso la primera vez que tu aplicación intercambia un código de autorización por tokens.

En Python, configura el parámetro access_type especificando access_type como un argumento de palabra clave cuando llames al método flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    include_granted_scopes='true')
state Se recomienda

Especifica cualquier valor de string que tu aplicación usa para mantener el estado entre la solicitud de autorización y la respuesta del servidor de autorización. El servidor muestra el valor exacto que envías como un par name=value en el componente de consulta de URL (?) de redirect_uri después de que el usuario otorga su consentimiento o rechaza la solicitud de acceso de tu aplicación.

Puedes usar este parámetro para varios fines, como dirigir al usuario al recurso correcto en tu aplicación, enviar nonces y mitigar la falsificación de solicitudes entre sitios. Como tu redirect_uri puede adivinarse, usar un valor state puede aumentar la seguridad de que una conexión entrante sea el resultado de una solicitud de autenticación. Si generas una string aleatoria o codificas el hash de una cookie o algún otro valor que captura el estado del cliente, puedes validar la respuesta para garantizar, además, que la solicitud y la respuesta se hayan originado en el mismo navegador, lo que brinda protección contra ataques como la falsificación de solicitudes entre sitios. Consulta la documentación de OpenID Connect para ver un ejemplo de cómo crear y confirmar un token state.

En Python, configura el parámetro state especificando state como un argumento de palabra clave cuando llames al método flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    state=sample_passthrough_value,
    include_granted_scopes='true')
include_granted_scopes Opcional

Permite que las aplicaciones usen la autorización incremental para solicitar acceso a permisos adicionales en contexto. Si configuras el valor de este parámetro en true y se otorga la solicitud de autorización, el nuevo token de acceso también cubrirá los permisos a los que el usuario otorgó acceso a la aplicación con anterioridad. Consulta la sección de autorización incremental para ver ejemplos.

En Python, configura el parámetro include_granted_scopes especificando include_granted_scopes como un argumento de palabra clave cuando llames al método flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    include_granted_scopes='true')
login_hint Opcional

Si tu aplicación sabe qué usuario está intentando autenticar, puede usar este parámetro para proporcionar una sugerencia al servidor de autenticación de Google. El servidor usa la sugerencia para simplificar el flujo de acceso, ya sea completando previamente el campo de correo electrónico en el formulario de acceso o seleccionando la sesión de acceso múltiple adecuada.

Establece el valor del parámetro en una dirección de correo electrónico o un identificador sub, que equivale al ID de Google del usuario.

En Python, configura el parámetro login_hint especificando login_hint como un argumento de palabra clave cuando llames al método flow.authorization_url:

authorization_url, state = flow.authorization_url(
    access_type='offline',
    login_hint='None',
    include_granted_scopes='true')
prompt Opcional

Una lista de mensajes para presentar al usuario, delimitados por espacios y que distinguen mayúsculas de minúsculas Si no especificas este parámetro, se le pedirá al usuario solo la primera vez que tu proyecto solicite acceso. Para obtener más información, consulta Cómo solicitar que se vuelva a dar consentimiento.

En Python, configura el parámetro prompt especificando prompt como un argumento de palabra clave cuando llames al método flow.authorization_url:

authorization_url, state = flow.authorization_url(
      access_type='offline',
      prompt='consent',
      include_granted_scopes='true')

Los valores posibles son:

none No muestres ninguna pantalla de autenticación ni de consentimiento. No se debe especificar con otros valores.
consent Solicita el consentimiento del usuario.
select_account Solicítale al usuario que seleccione una cuenta.

Ruby

Usa el archivo client_secrets.json que creaste para configurar un objeto de cliente en tu aplicación. Cuando configuras un objeto de cliente, especificas los permisos a los que tu aplicación necesita acceder, junto con la URL al extremo de autenticación de tu aplicación, que manejará la respuesta del servidor OAuth 2.0.

Por ejemplo, este código solicita acceso de solo lectura y sin conexión a la unidad de Google Drive de un usuario:

require 'google/apis/drive_v3'
require "googleauth"
require 'googleauth/stores/redis_token_store'

client_id = Google::Auth::ClientId.from_file('/path/to/client_secret.json')
scope = 'https://www.googleapis.com/auth/drive.metadata.readonly'
token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope, token_store, '/oauth2callback')

Your application uses the client object to perform OAuth 2.0 operations, such as generating authorization request URLs and applying access tokens to HTTP requests.

Node.js

The code snippet below creates a google.auth.OAuth2 object, which defines the parameters in the authorization request.

That object uses information from your client_secret.json file to identify your application. To ask for permissions from a user to retrieve an access token, you redirect them to a consent page. To create a consent page URL:

const {google} = require('googleapis');

/**
 * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
 * from the client_secret.json file. To get these credentials for your application, visit
 * https://console.cloud.google.com/apis/credentials.
 */
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for read-only Drive activity.
const scopes = [
  'https://www.googleapis.com/auth/drive.metadata.readonly'
];

// Generate a url that asks permissions for the Drive activity scope
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  /** Pass in the scopes array defined above.
    * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
  scope: scopes,
  // Enable incremental authorization. Recommended as a best practice.
  include_granted_scopes: true
});

Nota importante: refresh_token solo se muestra en la primera autorización. Obtén más detalles aquí.

HTTP/REST

El extremo de OAuth 2.0 de Google está en https://accounts.google.com/o/oauth2/v2/auth. Solo se puede acceder a este extremo a través de HTTPS. Se rechazan las conexiones HTTP sin formato.

El servidor de autorización de Google admite los siguientes parámetros de cadena de consulta para aplicaciones de servidor web:

Parámetros
client_id Obligatorio

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

redirect_uri Obligatorio

Determina a dónde redirecciona el servidor de la API al usuario después de que este completa el flujo de autorización. El valor debe coincidir exactamente con uno de los URI de redireccionamiento autorizados para el cliente OAuth 2.0, que configuraste en la API Console Credentials pagede tu cliente. Si este valor no coincide con un URI de redireccionamiento autorizado para el client_id proporcionado, verás un error redirect_uri_mismatch.

Ten en cuenta que los esquemas http o https, las mayúsculas y la barra final (“/”) deben coincidir.

response_type Obligatorio

Determina si el extremo de Google OAuth 2.0 muestra un código de autorización.

Establece el valor del parámetro en code para las aplicaciones de servidor web.

scope Obligatorio

Una lista delimitada por espacios de los permisos que identifican los recursos a los que tu aplicación podría acceder en nombre del usuario. Estos valores informan la pantalla de consentimiento que Google muestra al usuario.

Los permisos permiten que tu 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 tu aplicación. Por lo tanto, existe una relación inversa entre la cantidad de alcances solicitados y la probabilidad de obtener el consentimiento del usuario.

Recomendamos que tu aplicación solicite acceso a los permisos de autorización en contexto siempre que sea posible. Si solicitas acceso a los datos del usuario en contexto, mediante la autorización incremental, ayudas a los usuarios a comprender más fácilmente por qué tu aplicación necesita el acceso que solicita.

access_type Se recomienda

Indica si tu aplicación puede actualizar los tokens de acceso cuando el usuario no está presente en el navegador. Los valores de parámetro válidos son online, que es el valor predeterminado, y offline.

Establece el valor en offline si tu aplicación necesita actualizar los tokens de acceso cuando el usuario no está presente en el navegador. Este es el método para actualizar los tokens de acceso que se describe más adelante en este documento. Este valor le indica al servidor de autorización de Google que muestre un token de actualización y un token de acceso la primera vez que tu aplicación intercambia un código de autorización por tokens.

state Se recomienda

Especifica cualquier valor de string que tu aplicación usa para mantener el estado entre la solicitud de autorización y la respuesta del servidor de autorización. El servidor muestra el valor exacto que envías como un par name=value en el componente de consulta de URL (?) de redirect_uri después de que el usuario otorga su consentimiento o rechaza la solicitud de acceso de tu aplicación.

Puedes usar este parámetro para varios fines, como dirigir al usuario al recurso correcto en tu aplicación, enviar nonces y mitigar la falsificación de solicitudes entre sitios. Como tu redirect_uri puede adivinarse, usar un valor state puede aumentar la seguridad de que una conexión entrante sea el resultado de una solicitud de autenticación. Si generas una string aleatoria o codificas el hash de una cookie o algún otro valor que captura el estado del cliente, puedes validar la respuesta para garantizar, además, que la solicitud y la respuesta se hayan originado en el mismo navegador, lo que brinda protección contra ataques como la falsificación de solicitudes entre sitios. Consulta la documentación de OpenID Connect para ver un ejemplo de cómo crear y confirmar un token state.

include_granted_scopes Opcional

Permite que las aplicaciones usen la autorización incremental para solicitar acceso a permisos adicionales en contexto. Si configuras el valor de este parámetro en true y se otorga la solicitud de autorización, el nuevo token de acceso también cubrirá los permisos a los que el usuario otorgó acceso a la aplicación con anterioridad. Consulta la sección de autorización incremental para ver ejemplos.

login_hint Opcional

Si tu aplicación sabe qué usuario está intentando autenticar, puede usar este parámetro para proporcionar una sugerencia al servidor de autenticación de Google. El servidor usa la sugerencia para simplificar el flujo de acceso, ya sea completando previamente el campo de correo electrónico en el formulario de acceso o seleccionando la sesión de acceso múltiple adecuada.

Establece el valor del parámetro en una dirección de correo electrónico o un identificador sub, que equivale al ID de Google del usuario.

prompt Opcional

Una lista de mensajes para presentar al usuario, delimitados por espacios y que distinguen mayúsculas de minúsculas Si no especificas este parámetro, se le pedirá al usuario solo la primera vez que tu proyecto solicite acceso. Para obtener más información, consulta Cómo solicitar que se vuelva a dar consentimiento.

Los valores posibles son:

none No muestres ninguna pantalla de autenticación ni de consentimiento. No se debe especificar con otros valores.
consent Solicita el consentimiento del usuario.
select_account Solicítale al usuario que seleccione una cuenta.

Paso 2: Redireccionar al servidor de OAuth 2.0 de Google

Redireccionar al usuario al servidor de OAuth 2.0 de Google para iniciar el proceso de autenticación y autorización Por lo general, esto ocurre cuando tu aplicación necesita acceder a los datos del usuario por primera vez. En el caso de la autorización incremental, este paso también ocurre cuando tu aplicación necesita acceder por primera vez a recursos adicionales a los que aún no tiene permiso para acceder.

PHP

  1. Genera una URL para solicitar acceso del servidor de OAuth 2.0 de Google:
    $auth_url = $client->createAuthUrl();
  2. Redireccionar al usuario a $auth_url:
    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));

Python

En este ejemplo, se muestra cómo redireccionar al usuario a la URL de autorización mediante el framework de aplicaciones web Flask:

return flask.redirect(authorization_url)

Ruby

  1. Genera una URL para solicitar acceso del servidor de OAuth 2.0 de Google:
    auth_uri = authorizer.get_authorization_url(login_hint: user_id, request: request)
  2. Redireccionar al usuario a auth_uri

Node.js

  1. Usa la URL generada authorizationUrl del método generateAuthUrl del Paso 1 para solicitar acceso al servidor OAuth 2.0 de Google.
  2. Redireccionar al usuario a authorizationUrl
    res.writeHead(301, { "Location": authorizationUrl });

HTTP/REST

Sample redirect to Google's authorization server

An example URL is shown below, with line breaks and spaces for readability.

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 access_type=offline&
 include_granted_scopes=true&
 response_type=code&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

Después de crear la URL de la solicitud, redirecciona al usuario a ella.

El servidor OAuth 2.0 de Google autentica al usuario y obtiene su consentimiento para que tu aplicación acceda a los permisos solicitados. La respuesta se envía a tu aplicación con la URL de redireccionamiento que especificaste.

Paso 3: Google solicita el consentimiento del usuario

En este paso, el usuario decide si otorga a tu aplicación el acceso solicitado. En esta etapa, Google muestra una ventana de consentimiento que muestra el nombre de tu aplicación y los servicios de la API de Google a los que solicita permiso de acceso con las credenciales de autorización del usuario, así como un resumen de los permisos de acceso que se otorgarán. Luego, el usuario puede otorgar acceso a uno o más alcances solicitados por la aplicación, o rechazar la solicitud.

Tu aplicación no necesita realizar ninguna acción en esta etapa, ya que espera la respuesta del servidor OAuth 2.0 de Google que indique si se otorgó algún acceso. Esa respuesta se explica en el siguiente paso.

Errores

Las solicitudes al extremo de autorización de OAuth 2.0 de Google pueden mostrar mensajes de error para el usuario en lugar de los flujos de autenticación y autorización esperados. A continuación, se indican los códigos de error comunes y las soluciones sugeridas.

admin_policy_enforced

La Cuenta de Google no puede autorizar uno o más permisos solicitados debido a las políticas de su administrador de Google Workspace. Consulta el artículo de ayuda para administradores de Google Workspace: Controla qué aplicaciones internas y de terceros acceden a los datos de Google Workspace para obtener más información sobre cómo un administrador puede restringir el acceso a todos los permisos o permisos sensibles y restringidos hasta que se otorgue acceso de manera explícita a tu ID de cliente de OAuth.

disallowed_useragent

El extremo de autorización se muestra en un usuario-agente incorporado no permitido por las Políticas de OAuth 2.0 de Google.

Android

Los desarrolladores de Android pueden encontrar este mensaje de error cuando abren solicitudes de autorización en android.webkit.WebView. En su lugar, los desarrolladores deben usar bibliotecas de Android, como AppAuth para Android de OpenID Foundation o Acceso con Google para Android.

Los desarrolladores web pueden encontrar este error cuando una app para Android abre un vínculo web general en un usuario-agente incorporado y un usuario navega al extremo de autorización de OAuth 2.0 de Google desde tu sitio. Los desarrolladores deben permitir que los vínculos generales se abran en el controlador de vínculos predeterminado del sistema operativo, que incluye controladores de Android App Links o la app de navegador predeterminada. La biblioteca de Android Custom Tabs también es una opción compatible.

iOS

Los desarrolladores de iOS y macOS pueden encontrar este error cuando abren solicitudes de autorización en WKWebView. En su lugar, los desarrolladores deben usar bibliotecas de iOS, como AppAuth para iOS de OpenID Foundation o Acceso con Google para iOS.

Los desarrolladores web pueden encontrar este error cuando una app para iOS o macOS abra un vínculo web general en un usuario-agente incorporado y un usuario navegue al extremo de autorización de OAuth 2.0 de Google desde tu sitio. Los desarrolladores deben permitir que los vínculos generales se abran en el controlador de vínculos predeterminado del sistema operativo, que incluye controladores de vínculos universales o la app de navegador predeterminada. La biblioteca SFSafariViewController también es una opción compatible.

org_internal

El ID de cliente de OAuth en la solicitud es parte de un proyecto que limita el acceso a las Cuentas de Google en una organización de Google Cloud específica. Para obtener más información sobre esta opción de configuración, consulta la sección Tipo de usuario en el artículo de ayuda Configura la pantalla de consentimiento de OAuth.

invalid_client

El secreto del cliente de OAuth es incorrecto. Revisa la configuración del cliente OAuth, incluidos el ID de cliente y el secreto que se usaron para esta solicitud.

invalid_grant

Cuando actualizas un token de acceso o usas la autorización incremental, es posible que el token haya vencido o se haya invalidado. Vuelve a autenticar al usuario y solicita su consentimiento para obtener tokens nuevos. Si continúas viendo este error, asegúrate de que tu aplicación se haya configurado correctamente y de que estás usando los tokens y parámetros correctos en tu solicitud. De lo contrario, es posible que la cuenta de usuario se haya borrado o inhabilitado.

redirect_uri_mismatch

El redirect_uri que se pasa en la solicitud de autorización no coincide con un URI de redireccionamiento autorizado para el ID de cliente de OAuth. Revisa los URI de redireccionamiento autorizados en el Google API Console Credentials page.

El parámetro redirect_uri puede hacer referencia al flujo fuera de banda (OOB) de OAuth que dejó de estar disponible y ya no es compatible. Consulta la guía de migración para actualizar tu integración.

invalid_request

Se produjo un error con la solicitud que realizaste. Esto podría deberse a varios motivos:

  • La solicitud no tenía el formato correcto
  • Faltan parámetros obligatorios en la solicitud
  • La solicitud usa un método de autorización que Google no admite. Verifica que tu integración de OAuth use un método de integración recomendado

Paso 4: Controla la respuesta del servidor de OAuth 2.0

El servidor de OAuth 2.0 responde a la solicitud de acceso de tu aplicación con la URL especificada en la solicitud.

Si el usuario aprueba la solicitud de acceso, la respuesta contendrá un código de autorización. Si el usuario no aprueba la solicitud, esta contendrá un mensaje de error. El código de autorización o el mensaje de error que se muestra al servidor web aparece en la cadena de consulta, como se muestra a continuación:

Respuesta de error:

https://oauth2.example.com/auth?error=access_denied

Una respuesta de código de autorización:

https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7

Ejemplo de respuesta del servidor de OAuth 2.0

Puedes probar este flujo si haces clic en la siguiente URL de muestra, que solicita acceso de solo lectura para ver los metadatos de los archivos en tu Google Drive:

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 access_type=offline&
 include_granted_scopes=true&
 response_type=code&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

Después de completar el flujo de OAuth 2.0, se te debería redireccionar a http://localhost/oauth2callback, que probablemente generará un error 404 NOT FOUND, a menos que tu máquina local entregue un archivo en esa dirección. En el siguiente paso, se proporcionan más detalles sobre la información que se muestra en el URI cuando se redirecciona al usuario de vuelta a tu aplicación.

Paso 5: Intercambia el código de autorización por tokens de actualización y acceso

Después de que el servidor web recibe el código de autorización, puede intercambiarlo por un token de acceso.

PHP

Para intercambiar un código de autorización por un token de acceso, usa el método authenticate:

$client->authenticate($_GET['code']);

Puedes recuperar el token de acceso con el método getAccessToken:

$access_token = $client->getAccessToken();

Python

En tu página de devolución de llamada, usa la biblioteca google-auth para verificar la respuesta del servidor de autorización. Luego, usa el método flow.fetch_token para intercambiar el código de autorización en esa respuesta por un token de acceso:

state = flask.session['state']
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'],
    state=state)
flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

authorization_response = flask.request.url
flow.fetch_token(authorization_response=authorization_response)

# Store the credentials in the session.
# ACTION ITEM for developers:
#     Store user's access and refresh tokens in your data store if
#     incorporating this code into your real app.
credentials = flow.credentials
flask.session['credentials'] = {
    'token': credentials.token,
    'refresh_token': credentials.refresh_token,
    'token_uri': credentials.token_uri,
    'client_id': credentials.client_id,
    'client_secret': credentials.client_secret,
    'scopes': credentials.scopes}

Ruby

En tu página de devolución de llamada, usa la biblioteca googleauth para verificar la respuesta del servidor de autorización. Usa el método authorizer.handle_auth_callback_deferred para guardar el código de autorización y redireccionar a la URL que originalmente solicitó la autorización. Esto aplaza el intercambio de código y almacena temporalmente los resultados en la sesión del usuario.

  target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
  redirect target_url

Node.js

Para intercambiar un código de autorización por un token de acceso, usa el método getToken:

const url = require('url');

// Receive the callback from Google's OAuth 2.0 server.
if (req.url.startsWith('/oauth2callback')) {
  // Handle the OAuth 2.0 server response
  let q = url.parse(req.url, true).query;

  // Get access and refresh tokens (if access_type is offline)
  let { tokens } = await oauth2Client.getToken(q.code);
  oauth2Client.setCredentials(tokens);
}

HTTP/REST

Para intercambiar un código de autorización por un token de acceso, llama al extremo https://oauth2.googleapis.com/token y configura los siguientes parámetros:

Campos
client_id El ID de cliente obtenido de API Console Credentials page.
client_secret El secreto del cliente obtenido de API Console Credentials page.
code El código de autorización que se muestra en la solicitud inicial.
grant_type Como se define en la especificación de OAuth 2.0, el valor de este campo se debe establecer en authorization_code.
redirect_uri Se trata de uno de los URI de redireccionamiento enumerados para tu proyecto en el archivo Credentials page de API Consolecorrespondiente al client_id determinado.

En el siguiente fragmento, se muestra una solicitud de ejemplo:

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

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https%3A//oauth2.example.com/code&
grant_type=authorization_code

Para responder a esta solicitud, Google muestra un objeto JSON que contiene un token de acceso de corta duración y un token de actualización. Ten en cuenta que el token de actualización solo se muestra si la aplicación estableció el parámetro access_type en offline en la solicitud inicial al servidor de autorización de Google.

La respuesta contiene los siguientes campos:

Campos
access_token Es el token que envía la aplicación para autorizar una solicitud a la API de Google.
expires_in La vida útil restante del token de acceso, expresada en segundos.
refresh_token Un token que puedes usar para obtener un token de acceso nuevo. Los tokens de actualización son válidos hasta que el usuario revoque el acceso. De nuevo, este campo solo está presente en esta respuesta si estableces el parámetro access_type en offline en la solicitud inicial al servidor de autorización de Google.
scope Los permisos de acceso que otorga access_token, expresados como una lista de strings separadas por espacios y que distinguen mayúsculas de minúsculas.
token_type El tipo de token que se muestra. En este momento, el valor de este campo siempre se establece en Bearer.

En el siguiente fragmento, se muestra una respuesta de muestra:

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

Errores

Cuando intercambies el código de autorización por un token de acceso, es posible que encuentres el siguiente error en lugar de la respuesta esperada. A continuación, se indican los códigos de error comunes y las soluciones sugeridas.

invalid_grant

El código de autorización proporcionado no es válido o tiene un formato incorrecto. Para solicitar un código nuevo, reinicia el proceso de OAuth a fin de solicitar nuevamente el consentimiento del usuario.

Llama a las APIs de Google

PHP

Usa el token de acceso para llamar a las APIs de Google mediante los siguientes pasos:

  1. Si necesitas aplicar un token de acceso a un objeto Google\Client nuevo (por ejemplo, si almacenaste el token de acceso en una sesión de usuario), usa el método setAccessToken:
    $client->setAccessToken($access_token);
  2. Compila un objeto de servicio para la API a la que deseas llamar. Para compilar un objeto de servicio, debes proporcionar un objeto Google\Client autorizado al constructor de la API a la que deseas llamar. Por ejemplo, para llamar a la API de Drive:
    $drive = new Google\Service\Drive($client);
  3. Realiza solicitudes al servicio de la API mediante la interfaz que proporciona el objeto de servicio. Por ejemplo, para enumerar los archivos en la unidad de Google Drive del usuario autenticado, haz lo siguiente:
    $files = $drive->files->listFiles(array())->getItems();

Python

Después de obtener un token de acceso, tu aplicación puede usarlo para autorizar solicitudes a la API en nombre de una cuenta de usuario o de servicio determinada. Usa las credenciales de autorización específicas del usuario a fin de compilar un objeto de servicio para la API a la que deseas llamar y, luego, usa ese objeto a fin de realizar solicitudes autorizadas a la API.

  1. Compila un objeto de servicio para la API a la que deseas llamar. Para compilar un objeto de servicio, llama al método build de la biblioteca googleapiclient.discovery con el nombre y la versión de la API y las credenciales de usuario: Por ejemplo, para llamar a la versión 3 de la API de Drive:
    from googleapiclient.discovery import build
    
    drive = build('drive', 'v2', credentials=credentials)
  2. Realiza solicitudes al servicio de la API mediante la interfaz que proporciona el objeto de servicio. Por ejemplo, para enumerar los archivos en la unidad de Google Drive del usuario autenticado, haz lo siguiente:
    files = drive.files().list().execute()

Ruby

Después de obtener un token de acceso, la aplicación puede usarlo para realizar solicitudes a la API en nombre de una cuenta de usuario o de servicio determinada. Usa las credenciales de autorización específicas del usuario a fin de compilar un objeto de servicio para la API a la que deseas llamar y, luego, usa ese objeto a fin de realizar solicitudes autorizadas a la API.

  1. Compila un objeto de servicio para la API a la que deseas llamar. Por ejemplo, para llamar a la versión 3 de la API de Drive, usa lo siguiente:
    drive = Google::Apis::DriveV3::DriveService.new
  2. Configura las credenciales en el servicio:
    drive.authorization = credentials
  3. Realiza solicitudes al servicio de la API mediante la interfaz que proporciona el objeto de servicio. Por ejemplo, para enumerar los archivos en la unidad de Google Drive del usuario autenticado, haz lo siguiente:
    files = drive.list_files

De manera alternativa, se puede proporcionar la autorización por método si se proporciona el parámetro options a un método:

files = drive.list_files(options: { authorization: credentials })

Node.js

Después de obtener un token de acceso y configurarlo en el objeto OAuth2, usa el objeto para llamar a las APIs de Google. Tu aplicación puede usar ese token para autorizar solicitudes a la API en nombre de una cuenta de usuario o de servicio determinada. Compila un objeto de servicio para la API a la que deseas llamar.

const { google } = require('googleapis');

// Example of using Google Drive API to list filenames in user's Drive.
const drive = google.drive('v3');
drive.files.list({
  auth: oauth2Client,
  pageSize: 10,
  fields: 'nextPageToken, files(id, name)',
}, (err1, res1) => {
  if (err1) return console.log('The API returned an error: ' + err1);
  const files = res1.data.files;
  if (files.length) {
    console.log('Files:');
    files.map((file) => {
      console.log(`${file.name} (${file.id})`);
    });
  } else {
    console.log('No files found.');
  }
});

HTTP/REST

Después de que la aplicación obtiene un token de acceso, puedes usarlo para realizar 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 mediante la inclusión de un parámetro de consulta access_token o un valor Bearer del encabezado HTTP Authorization. Siempre que sea posible, se prefiere el encabezado HTTP, ya que las cadenas 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, cuando llamas a la API de Archivos de Drive).

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

Ejemplos de HTTP GET

Una llamada al extremo drive.files (la API de Archivos de Drive) 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 con el parámetro de cadena 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. En el siguiente ejemplo, se 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, la opción de parámetro de cadena de consulta:

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

Ejemplo completo

En el siguiente ejemplo, se imprime una lista de archivos en formato JSON en la unidad de Google Drive de un usuario después de que este se autentica y otorga su consentimiento para que la aplicación acceda a sus metadatos de Drive.

PHP

Para ejecutar este ejemplo, haz lo siguiente:

  1. En API Console, agrega la URL de la máquina local a la lista de URLs de redireccionamiento. Por ejemplo, agrega http://localhost:8080.
  2. Crea un directorio nuevo y cámbialo. Por ejemplo:
    mkdir ~/php-oauth2-example
    cd ~/php-oauth2-example
  3. Instala la biblioteca cliente de la API de Google para PHP con Composer:
    composer require google/apiclient:^2.10
  4. Crea los archivos index.php y oauth2callback.php con el siguiente contenido.
  5. Ejecuta el ejemplo con un servidor web configurado para entregar PHP. Si usas PHP 5.6 o una versión más reciente, puedes usar el servidor web de prueba integrado de PHP:
    php -S localhost:8080 ~/php-oauth2-example
    .

index.php

<?php
require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google\Client();
$client->setAuthConfig('client_secrets.json');
$client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY);

if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
  $client->setAccessToken($_SESSION['access_token']);
  $drive = new Google\Service\Drive($client);
  $files = $drive->files->listFiles(array())->getItems();
  echo json_encode($files);
} else {
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

oauth2callback.php

<?php
require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google\Client();
$client->setAuthConfigFile('client_secrets.json');
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
$client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY);

if (! isset($_GET['code'])) {
  $auth_url = $client->createAuthUrl();
  header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
  $client->authenticate($_GET['code']);
  $_SESSION['access_token'] = $client->getAccessToken();
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

Python

En este ejemplo, se usa el framework Flask. Ejecuta una aplicación web en http://localhost:8080 que te permite probar el flujo de OAuth 2.0. Si vas a esa URL, deberías ver cuatro vínculos:

  • Probar una solicitud a la API: Este vínculo dirige a una página que intenta ejecutar una solicitud a la API de muestra. Si es necesario, inicia el flujo de autorización. Si se ejecuta de forma correcta, la página muestra la respuesta de la API.
  • Prueba directamente el flujo de autenticación: Este vínculo dirige a una página que intenta enviar al usuario a través del flujo de autorización. La app solicita permiso para enviar solicitudes autorizadas a la API en nombre del usuario.
  • Revocar credenciales actuales: Este vínculo dirige a una página que revoca los permisos que el usuario ya otorgó a la aplicación.
  • Borrar credenciales de sesión de Flask: Este vínculo borra las credenciales de autorización que están almacenadas en la sesión de Flask. Esto te permite ver lo que sucedería si un usuario que ya había otorgado permiso a tu app intentara ejecutar una solicitud a la API en una sesión nueva. También te permite ver la respuesta de la API que obtendría tu app si un usuario hubiera revocado los permisos otorgados, y la app aún intentó autorizar una solicitud con un token de acceso revocado.
# -*- coding: utf-8 -*-

import os
import flask
import requests

import google.oauth2.credentials
import google_auth_oauthlib.flow
import googleapiclient.discovery

# This variable specifies the name of a file that contains the OAuth 2.0
# information for this application, including its client_id and client_secret.
CLIENT_SECRETS_FILE = "client_secret.json"

# This OAuth 2.0 access scope allows for full read/write access to the
# authenticated user's account and requires requests to use an SSL connection.
SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly']
API_SERVICE_NAME = 'drive'
API_VERSION = 'v2'

app = flask.Flask(__name__)
# Note: A secret key is included in the sample so that it works.
# If you use this code in your application, replace this with a truly secret
# key. See https://flask.palletsprojects.com/quickstart/#sessions.
app.secret_key = 'REPLACE ME - this value is here as a placeholder.'


@app.route('/')
def index():
  return print_index_table()


@app.route('/test')
def test_api_request():
  if 'credentials' not in flask.session:
    return flask.redirect('authorize')

  # Load credentials from the session.
  credentials = google.oauth2.credentials.Credentials(
      **flask.session['credentials'])

  drive = googleapiclient.discovery.build(
      API_SERVICE_NAME, API_VERSION, credentials=credentials)

  files = drive.files().list().execute()

  # Save credentials back to session in case access token was refreshed.
  # ACTION ITEM: In a production app, you likely want to save these
  #              credentials in a persistent database instead.
  flask.session['credentials'] = credentials_to_dict(credentials)

  return flask.jsonify(**files)


@app.route('/authorize')
def authorize():
  # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps.
  flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
      CLIENT_SECRETS_FILE, scopes=SCOPES)

  # The URI created here must exactly match one of the authorized redirect URIs
  # for the OAuth 2.0 client, which you configured in the API Console. If this
  # value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch'
  # error.
  flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

  authorization_url, state = flow.authorization_url(
      # Enable offline access so that you can refresh an access token without
      # re-prompting the user for permission. Recommended for web server apps.
      access_type='offline',
      # Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes='true')

  # Store the state so the callback can verify the auth server response.
  flask.session['state'] = state

  return flask.redirect(authorization_url)


@app.route('/oauth2callback')
def oauth2callback():
  # Specify the state when creating the flow in the callback so that it can
  # verified in the authorization server response.
  state = flask.session['state']

  flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
      CLIENT_SECRETS_FILE, scopes=SCOPES, state=state)
  flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

  # Use the authorization server's response to fetch the OAuth 2.0 tokens.
  authorization_response = flask.request.url
  flow.fetch_token(authorization_response=authorization_response)

  # Store credentials in the session.
  # ACTION ITEM: In a production app, you likely want to save these
  #              credentials in a persistent database instead.
  credentials = flow.credentials
  flask.session['credentials'] = credentials_to_dict(credentials)

  return flask.redirect(flask.url_for('test_api_request'))


@app.route('/revoke')
def revoke():
  if 'credentials' not in flask.session:
    return ('You need to <a href="/authorize">authorize</a> before ' +
            'testing the code to revoke credentials.')

  credentials = google.oauth2.credentials.Credentials(
    **flask.session['credentials'])

  revoke = requests.post('https://oauth2.googleapis.com/revoke',
      params={'token': credentials.token},
      headers = {'content-type': 'application/x-www-form-urlencoded'})

  status_code = getattr(revoke, 'status_code')
  if status_code == 200:
    return('Credentials successfully revoked.' + print_index_table())
  else:
    return('An error occurred.' + print_index_table())


@app.route('/clear')
def clear_credentials():
  if 'credentials' in flask.session:
    del flask.session['credentials']
  return ('Credentials have been cleared.<br><br>' +
          print_index_table())


def credentials_to_dict(credentials):
  return {'token': credentials.token,
          'refresh_token': credentials.refresh_token,
          'token_uri': credentials.token_uri,
          'client_id': credentials.client_id,
          'client_secret': credentials.client_secret,
          'scopes': credentials.scopes}

def print_index_table():
  return ('<table>' +
          '<tr><td><a href="/test">Test an API request</a></td>' +
          '<td>Submit an API request and see a formatted JSON response. ' +
          '    Go through the authorization flow if there are no stored ' +
          '    credentials for the user.</td></tr>' +
          '<tr><td><a href="/authorize">Test the auth flow directly</a></td>' +
          '<td>Go directly to the authorization flow. If there are stored ' +
          '    credentials, you still might not be prompted to reauthorize ' +
          '    the application.</td></tr>' +
          '<tr><td><a href="/revoke">Revoke current credentials</a></td>' +
          '<td>Revoke the access token associated with the current user ' +
          '    session. After revoking credentials, if you go to the test ' +
          '    page, you should see an <code>invalid_grant</code> error.' +
          '</td></tr>' +
          '<tr><td><a href="/clear">Clear Flask session credentials</a></td>' +
          '<td>Clear the access token currently stored in the user session. ' +
          '    After clearing the token, if you <a href="/test">test the ' +
          '    API request</a> again, you should go back to the auth flow.' +
          '</td></tr></table>')


if __name__ == '__main__':
  # When running locally, disable OAuthlib's HTTPs verification.
  # ACTION ITEM for developers:
  #     When running in production *do not* leave this option enabled.
  os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'

  # Specify a hostname and port that are set as a valid redirect URI
  # for your API project in the Google API Console.
  app.run('localhost', 8080, debug=True)

Ruby

En este ejemplo, se usa el marco de trabajo Sinatra.

require 'google/apis/drive_v3'
require 'sinatra'
require 'googleauth'
require 'googleauth/stores/redis_token_store'

configure do
  enable :sessions

  set :client_id, Google::Auth::ClientId.from_file('/path/to/client_secret.json')
  set :scope, Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY
  set :token_store, Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)
  set :authorizer, Google::Auth::WebUserAuthorizer.new(settings.client_id, settings.scope, settings.token_store, '/oauth2callback')
end

get '/' do
  user_id = settings.client_id.id
  credentials = settings.authorizer.get_credentials(user_id, request)
  if credentials.nil?
    redirect settings.authorizer.get_authorization_url(login_hint: user_id, request: request)
  end
  drive = Google::Apis::DriveV3::DriveService.new
  files = drive.list_files(options: { authorization: credentials })
  "<pre>#{JSON.pretty_generate(files.to_h)}</pre>"
end

get '/oauth2callback' do
  target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
  redirect target_url
end

Node.js

Para ejecutar este ejemplo, haz lo siguiente:

  1. En API Console, agrega la URL de la máquina local a la lista de URLs de redireccionamiento. Por ejemplo, agrega http://localhost.
  2. Asegúrate de tener instalada la LTS de mantenimiento, la LTS activa o la versión actual de Node.js.
  3. Crea un directorio nuevo y cámbialo. Por ejemplo:
    mkdir ~/nodejs-oauth2-example
    cd ~/nodejs-oauth2-example
  4. Install the Google API Client Library for Node.js using npm:
    npm install googleapis
  5. Crea los archivos main.js con el siguiente contenido.
  6. Ejecuta el ejemplo:
    node .\main.js

main.js

const http = require('http');
const https = require('https');
const url = require('url');
const { google } = require('googleapis');

/**
 * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI.
 * To get these credentials for your application, visit
 * https://console.cloud.google.com/apis/credentials.
 */
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for read-only Drive activity.
const scopes = [
  'https://www.googleapis.com/auth/drive.metadata.readonly'
];

// Generate a url that asks permissions for the Drive activity scope
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  /** Pass in the scopes array defined above.
    * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
  scope: scopes,
  // Enable incremental authorization. Recommended as a best practice.
  include_granted_scopes: true
});

/* Global variable that stores user credential in this code example.
 * ACTION ITEM for developers:
 *   Store user's refresh token in your data store if
 *   incorporating this code into your real app.
 *   For more information on handling refresh tokens,
 *   see https://github.com/googleapis/google-api-nodejs-client#handling-refresh-tokens
 */
let userCredential = null;

async function main() {
  const server = http.createServer(async function (req, res) {
    // Example on redirecting user to Google's OAuth 2.0 server.
    if (req.url == '/') {
      res.writeHead(301, { "Location": authorizationUrl });
    }

    // Receive the callback from Google's OAuth 2.0 server.
    if (req.url.startsWith('/oauth2callback')) {
      // Handle the OAuth 2.0 server response
      let q = url.parse(req.url, true).query;

      if (q.error) { // An error response e.g. error=access_denied
        console.log('Error:' + q.error);
      } else { // Get access and refresh tokens (if access_type is offline)
        let { tokens } = await oauth2Client.getToken(q.code);
        oauth2Client.setCredentials(tokens);

        /** Save credential to the global variable in case access token was refreshed.
          * ACTION ITEM: In a production app, you likely want to save the refresh token
          *              in a secure persistent database instead. */
        userCredential = tokens;

        // Example of using Google Drive API to list filenames in user's Drive.
        const drive = google.drive('v3');
        drive.files.list({
          auth: oauth2Client,
          pageSize: 10,
          fields: 'nextPageToken, files(id, name)',
        }, (err1, res1) => {
          if (err1) return console.log('The API returned an error: ' + err1);
          const files = res1.data.files;
          if (files.length) {
            console.log('Files:');
            files.map((file) => {
              console.log(`${file.name} (${file.id})`);
            });
          } else {
            console.log('No files found.');
          }
        });
      }
    }

    // Example on revoking a token
    if (req.url == '/revoke') {
      // Build the string for the POST request
      let postData = "token=" + userCredential.access_token;

      // Options for POST request to Google's OAuth 2.0 server to revoke a token
      let postOptions = {
        host: 'oauth2.googleapis.com',
        port: '443',
        path: '/revoke',
        method: 'POST',
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          'Content-Length': Buffer.byteLength(postData)
        }
      };

      // Set up the request
      const postReq = https.request(postOptions, function (res) {
        res.setEncoding('utf8');
        res.on('data', d => {
          console.log('Response: ' + d);
        });
      });

      postReq.on('error', error => {
        console.log(error)
      });

      // Post the request with data
      postReq.write(postData);
      postReq.end();
    }
    res.end();
  }).listen(80);
}
main().catch(console.error);

HTTP/REST

En este ejemplo de Python, se usa el framework de Flask y la biblioteca de Requests para demostrar el flujo web de OAuth 2.0. Recomendamos usar la biblioteca cliente de la API de Google para Python en este flujo. (en el ejemplo de la pestaña de Python se usa la biblioteca cliente).

import json

import flask
import requests


app = flask.Flask(__name__)

CLIENT_ID = '123456789.apps.googleusercontent.com'
CLIENT_SECRET = 'abc123'  # Read from a file or environmental variable in a real app
SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly'
REDIRECT_URI = 'http://example.com/oauth2callback'


@app.route('/')
def index():
  if 'credentials' not in flask.session:
    return flask.redirect(flask.url_for('oauth2callback'))
  credentials = json.loads(flask.session['credentials'])
  if credentials['expires_in'] <= 0:
    return flask.redirect(flask.url_for('oauth2callback'))
  else:
    headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])}
    req_uri = 'https://www.googleapis.com/drive/v2/files'
    r = requests.get(req_uri, headers=headers)
    return r.text


@app.route('/oauth2callback')
def oauth2callback():
  if 'code' not in flask.request.args:
    auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code'
                '&client_id={}&redirect_uri={}&scope={}').format(CLIENT_ID, REDIRECT_URI, SCOPE)
    return flask.redirect(auth_uri)
  else:
    auth_code = flask.request.args.get('code')
    data = {'code': auth_code,
            'client_id': CLIENT_ID,
            'client_secret': CLIENT_SECRET,
            'redirect_uri': REDIRECT_URI,
            'grant_type': 'authorization_code'}
    r = requests.post('https://oauth2.googleapis.com/token', data=data)
    flask.session['credentials'] = r.text
    return flask.redirect(flask.url_for('index'))


if __name__ == '__main__':
  import uuid
  app.secret_key = str(uuid.uuid4())
  app.debug = False
  app.run()

Reglas de validación de URI de redireccionamiento

Google aplica las siguientes reglas de validación para redireccionar los URI para ayudar a los desarrolladores a proteger sus aplicaciones. Tus URI de redireccionamiento deben cumplir con estas reglas. Consulta la sección 3 de RFC 3986 para obtener la definición de dominio, host, ruta de acceso, consulta, esquema y la información del usuario, que se menciona a continuación.

Reglas de validación
Esquema

Los URI de redireccionamiento deben usar el esquema HTTPS, no HTTP simple. Los URI de host local (incluidos los URI de direcciones IP de localhost) están exentos de esta regla.

Host

Los hosts no pueden ser direcciones IP sin procesar. Las direcciones IP de Localhost están exentas de esta regla.

Dominio
  • Los TLD de host (dominios de nivel superior) deben pertenecer a la lista de sufijos públicos.
  • Los dominios de host no pueden ser “googleusercontent.com”.
  • Los URI de redireccionamiento no pueden contener dominios de acortadores de URL (p.ej., goo.gl), a menos que la app sea propietaria del dominio. Además, si una app que posee un dominio de acortamiento elige redireccionar a ese dominio, ese URI de redireccionamiento debe contener “/google-callback/” en su ruta de acceso o terminar con “/google-callback”.
  • Información del usuario

    Los URI de redireccionamiento no pueden contener el subcomponente userinfo.

    Ruta de acceso

    Los URI de redireccionamiento no pueden contener un recorrido de ruta de acceso (también llamado retroceso de directorio), que está representado por un “/..” o “\..”, o su codificación de URL.

    Consulta

    Los URI de redireccionamiento no pueden contener redireccionamientos abiertos.

    Fragmento

    Los URI de redireccionamiento no pueden contener el componente del fragmento.

    Caracteres Los URI de redireccionamiento no pueden contener ciertos caracteres, como los siguientes:
    • Caracteres comodín ('*')
    • Caracteres ASCII no imprimibles
    • Codificaciones de porcentaje no válidas (cualquier codificación de porcentaje que no siga la codificación de URL de un signo de porcentaje seguido de dos dígitos hexadecimales)
    • Caracteres nulos (un carácter NULL codificado, p.ej., %00, %C0%80)

    Autorización incremental

    En el protocolo OAuth 2.0, tu app solicita autorización para acceder a los recursos, que se identifican por alcances. Se considera una práctica recomendada para la experiencia del usuario solicitar autorización de los recursos en el momento en que los necesitas. Para habilitar esa práctica, el servidor de autorización de Google admite la autorización incremental. Esta función te permite solicitar los permisos a medida que son necesarios y, si el usuario otorga permiso para el permiso nuevo, muestra un código de autorización que puede intercambiarse por un token que contiene todos los permisos que el usuario le otorgó al proyecto.

    Por ejemplo, es posible que una app que permita a las personas crear muestras de pistas musicales y crear mezclas necesite muy pocos recursos al momento de acceder, quizás nada más que el nombre de la persona que accede. Sin embargo, para guardar una combinación completa, se requerirá acceso a su unidad de Google Drive. Para la mayoría de las personas, sería natural que se les pidiera acceso a su unidad de Google Drive solo en el momento en que la app realmente lo necesitaba.

    En este caso, en el momento del acceso, la app puede solicitar los permisos openid y profile para realizar un acceso básico y, luego, solicitar el permiso https://www.googleapis.com/auth/drive.file en el momento de la primera solicitud para guardar una combinación.

    A fin de implementar la autorización incremental, debes completar el flujo normal para solicitar un token de acceso, pero asegúrate de que la solicitud de autorización incluya los permisos otorgados anteriormente. Este enfoque permite que tu app evite tener que administrar varios tokens de acceso.

    Las siguientes reglas se aplican a un token de acceso obtenido de una autorización incremental:

    • El token se puede usar para acceder a los recursos correspondientes a cualquiera de los permisos incluidos en la nueva autorización combinada.
    • Cuando usas el token de actualización para la autorización combinada a fin de obtener un token de acceso, este representa la autorización combinada y se puede usar para cualquiera de los valores de scope incluidos en la respuesta.
    • La autorización combinada incluye todos los alcances que el usuario otorgó al proyecto de API, incluso si los otorgamientos se solicitaron a diferentes clientes. Por ejemplo, si un usuario otorgara acceso a un alcance mediante el cliente para computadoras de escritorio de una aplicación y, luego, otorgara otro alcance a la misma aplicación a través de un cliente móvil, la autorización combinada incluiría ambos alcances.
    • Si revocas un token que representa una autorización combinada, se revocará de forma simultánea el acceso a todos los permisos de esa autorización en nombre del usuario asociado.

    Las muestras de código de lenguaje específico del Paso 1: Configura los parámetros de autorización y la URL de redireccionamiento HTTP/REST de muestra del Paso 2: Redireccionamiento al servidor OAuth 2.0 de Google usan autorización incremental. En las siguientes muestras de código, también se indica el código que debes agregar para usar la autorización incremental.

    PHP

    $client->setIncludeGrantedScopes(true);

    Python

    En Python, establece el argumento de palabra clave include_granted_scopes en true para asegurarte de que una solicitud de autorización incluya permisos otorgados con anterioridad. Es muy posible que include_granted_scopes no sea el único argumento de palabra clave que establezcas, como se muestra en el siguiente ejemplo.

    authorization_url, state = flow.authorization_url(
        # Enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true')

    Ruby

    auth_client.update!(
      :additional_parameters => {"include_granted_scopes" => "true"}
    )

    Node.js

    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true
    });
    

    HTTP/REST

    GET https://accounts.google.com/o/oauth2/v2/auth?
      client_id=your_client_id&
      response_type=code&
      state=state_parameter_passthrough_value&
      scope=https%3A//www.googleapis.com/auth/drive.file&
      redirect_uri=https%3A//oauth2.example.com/code&
      prompt=consent&
      include_granted_scopes=true

    Actualiza un token de acceso (acceso sin conexión)

    Los tokens de acceso vencen periódicamente y se dejan de ser 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.

    • Si usas una biblioteca cliente de la API de Google, el objeto cliente actualiza el token de acceso según sea necesario, siempre y cuando configures ese objeto para el acceso sin conexión.
    • Si no usas una biblioteca cliente, debes establecer el parámetro de búsqueda HTTP access_type en offline cuando redireccionas al usuario al servidor OAuth 2.0 de Google. En ese caso, el servidor de autorización de Google mostrará un token de actualización cuando intercambies un código de autorización por un token de acceso. Luego, si el token de acceso vence (o en cualquier otro momento), puedes usar un token de actualización para obtener un token de acceso nuevo.

    Solicitar acceso sin conexión es un requisito para cualquier aplicación que necesite acceder a una API de Google cuando el usuario no está presente. Por ejemplo, una app que realiza servicios de copia de seguridad o ejecuta acciones en momentos predeterminados debe poder actualizar su token de acceso cuando el usuario no esté presente. El estilo de acceso predeterminado se denomina online.

    Las aplicaciones web del servidor, las aplicaciones instaladas y los dispositivos obtienen tokens de actualización durante el proceso de autorización. Por lo general, los tokens de actualización no se usan en aplicaciones web del cliente (JavaScript).

    PHP

    Si tu aplicación necesita acceso sin conexión a una API de Google, establece el tipo de acceso del cliente de la API en offline:

    $client->setAccessType("offline");

    Después de que un usuario otorga acceso sin conexión a los permisos solicitados, puedes seguir usando el cliente de la API para acceder a las APIs de Google en nombre del usuario cuando no tenga conexión. El objeto de cliente actualizará el token de acceso según sea necesario.

    Python

    En Python, establece el argumento de palabra clave access_type en offline para asegurarte de poder actualizar el token de acceso sin tener que volver a solicitar permiso al usuario. Es muy posible que access_type no sea el único argumento de palabra clave que establezcas, como se muestra en el siguiente ejemplo.

    authorization_url, state = flow.authorization_url(
        # Enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true')

    Después de que un usuario otorga acceso sin conexión a los permisos solicitados, puedes seguir usando el cliente de la API para acceder a las APIs de Google en nombre del usuario cuando no tenga conexión. El objeto de cliente actualizará el token de acceso según sea necesario.

    Ruby

    Si tu aplicación necesita acceso sin conexión a una API de Google, establece el tipo de acceso del cliente de la API en offline:

    auth_client.update!(
      :additional_parameters => {"access_type" => "offline"}
    )

    Después de que un usuario otorga acceso sin conexión a los permisos solicitados, puedes seguir usando el cliente de la API para acceder a las APIs de Google en nombre del usuario cuando no tenga conexión. El objeto de cliente actualizará el token de acceso según sea necesario.

    Node.js

    Si tu aplicación necesita acceso sin conexión a una API de Google, establece el tipo de acceso del cliente de la API en offline:

    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true
    });
    

    Después de que un usuario otorga acceso sin conexión a los permisos solicitados, puedes seguir usando el cliente de la API para acceder a las APIs de Google en nombre del usuario cuando no tenga conexión. El objeto de cliente actualizará el token de acceso según sea necesario.

    Los tokens de acceso vencen. Esta biblioteca usará automáticamente un token de actualización para obtener un nuevo token de acceso si está a punto de caducar. Una forma fácil de asegurarte de almacenar los tokens más recientes es usar el evento tokens:

    oauth2Client.on('tokens', (tokens) => {
      if (tokens.refresh_token) {
        // store the refresh_token in your secure persistent database
        console.log(tokens.refresh_token);
      }
      console.log(tokens.access_token);
    });

    Este evento de tokens solo ocurre en la primera autorización, y debes establecer tu access_type en offline cuando llames al método generateAuthUrl para recibir el token de actualización. Si ya le diste a tu app los permisos necesarios sin configurar las restricciones adecuadas para recibir un token de actualización, deberás volver a autorizar a la aplicación para que reciba un token de actualización nuevo.

    Para configurar refresh_token más adelante, puedes usar el método setCredentials:

    oauth2Client.setCredentials({
      refresh_token: `STORED_REFRESH_TOKEN`
    });
    

    Una vez que el cliente tenga un token de actualización, los tokens de acceso se adquirirán y actualizarán automáticamente en la próxima llamada a la API.

    HTTP/REST

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

    Campos
    client_id El ID de cliente obtenido de API Console.
    client_secret El secreto del 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 de código de autorización.

    En el siguiente fragmento, se muestra una solicitud de ejemplo:

    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 una respuesta de ejemplo:

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

    Ten en cuenta que existen límites para la cantidad de tokens de actualización que se emitirán: uno por combinación de cliente y usuario, y otro por usuario para todos los clientes. Debes guardar los tokens de actualización en un almacenamiento a largo plazo y seguir usándolos mientras sean válidos. Si tu aplicación solicita demasiados tokens de actualización, podría alcanzar estos límites, en cuyo caso los tokens de actualización más antiguos dejarán de funcionar.

    Revoca un token

    En algunos casos, es posible que el usuario desee revocar el acceso otorgado a una aplicación. El usuario puede revocar el acceso a través de la Configuración de la cuenta. Para obtener más información, consulta el documento de asistencia Cómo quitar el acceso a sitios o apps de Sitios y apps de terceros con acceso a tu cuenta.

    También es posible que una aplicación revoque de forma programática el acceso que se le otorgó. La revocación programática es importante en los casos en que un usuario anula la suscripción, quita una aplicación o si los recursos de la API que requiere una app 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.

    PHP

    Para revocar un token de manera programática, llama a revokeToken():

    $client->revokeToken();

    Python

    Para revocar un token de manera programática, realiza una solicitud a https://oauth2.googleapis.com/revoke que incluya el token como parámetro y establezca el encabezado Content-Type:

    requests.post('https://oauth2.googleapis.com/revoke',
        params={'token': credentials.token},
        headers = {'content-type': 'application/x-www-form-urlencoded'})

    Ruby

    Para revocar un token de manera programática, realiza una solicitud HTTP al extremo oauth2.revoke:

    uri = URI('https://oauth2.googleapis.com/revoke')
    response = Net::HTTP.post_form(uri, 'token' => auth_client.access_token)
    

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

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

    Node.js

    Para revocar un token de manera programática, realiza una solicitud HTTPS POST al extremo /revoke:

    const https = require('https');
    
    // Build the string for the POST request
    let postData = "token=" + userCredential.access_token;
    
    // Options for POST request to Google's OAuth 2.0 server to revoke a token
    let postOptions = {
      host: 'oauth2.googleapis.com',
      port: '443',
      path: '/revoke',
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': Buffer.byteLength(postData)
      }
    };
    
    // Set up the request
    const postReq = https.request(postOptions, function (res) {
      res.setEncoding('utf8');
      res.on('data', d => {
        console.log('Response: ' + d);
      });
    });
    
    postReq.on('error', error => {
      console.log(error)
    });
    
    // Post the request with data
    postReq.write(postData);
    postReq.end();
    

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

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

    HTTP/REST

    Para revocar un token de manera programática, tu aplicación envía 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 de acceso o de actualización. Si se trata de un token de acceso y tiene un token de actualización correspondiente, el token de actualización también se revocará.

    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.