Uso de OAuth 2.0 para aplicaciones de servidor web

Este documento explica cómo las aplicaciones de servidor web utilizan las bibliotecas cliente de API de Google o los puntos finales de Google OAuth 2.0 para implementar la autorización de OAuth 2.0 para acceder a las API de Google.

OAuth 2.0 permite a los usuarios compartir datos específicos con una aplicación mientras mantienen la privacidad de sus nombres de usuario, contraseñas y otra información. Por ejemplo, una aplicación puede usar OAuth 2.0 para obtener permiso de los usuarios para almacenar archivos en sus Google Drives.

Este flujo de OAuth 2.0 es específicamente para la autorización del usuario. Está diseñado 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 haya abandonado la aplicación.

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

Bibliotecas cliente

Los ejemplos específicos del idioma de esta página utilizan las bibliotecas cliente de la API de Google para implementar la autorización OAuth 2.0. Para ejecutar los ejemplos de código, primero debe instalar la biblioteca cliente para su idioma.

Cuando usa una biblioteca de cliente de API de Google para manejar el flujo de OAuth 2.0 de su aplicación, la biblioteca de cliente realiza muchas acciones que la aplicación debería manejar por sí sola. 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 URL de redireccionamiento correctas y ayuda a implementar controladores de redireccionamiento que intercambian códigos de autorización por tokens de acceso.

Las bibliotecas cliente están disponibles para los siguientes idiomas:

Prerrequisitos

Habilite las API para su proyecto

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

Para habilitar una API para su proyecto:

  1. Open the API Library en el Google API Console.
  2. If prompted, select a project, or create a new one.
  3. El API Library enumera todas las API disponibles, agrupadas por familia de productos y popularidad. Si la API que desea habilitar no está visible en la lista, utilice la función de búsqueda para encontrarla o haga clic en Ver todo en la familia de productos a la que pertenece.
  4. Seleccione la API que desea habilitar, 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.

Crear credenciales de autorización

Cualquier aplicación que use OAuth 2.0 para acceder a las API de Google debe tener credenciales de autorización que identifiquen la aplicación en el servidor OAuth 2.0 de Google. Los siguientes pasos explican cómo crear credenciales para su proyecto. Luego, sus aplicaciones pueden usar las credenciales para acceder a las API que haya habilitado para ese proyecto.

  1. Go to the Credentials page.
  2. Haga clic en Crear credenciales> ID de cliente de OAuth .
  3. Seleccione el tipo de aplicación de la aplicación web .
  4. Complete el formulario y haga clic en Crear . Las aplicaciones que utilizan lenguajes y marcos como PHP, Java, Python, Ruby y .NET deben especificar URI de redireccionamiento autorizados. Los URI de redireccionamiento son los puntos finales a los que el servidor OAuth 2.0 puede enviar respuestas. Estos puntos finales deben cumplir con las reglas de validación de Google .

    Para las pruebas, puede especificar URI que hagan referencia a la máquina local, como http://localhost:8080 . Teniendo esto en cuenta, tenga en cuenta que todos los ejemplos de este documento utilizan http://localhost:8080 como URI de redireccionamiento.

    Le recomendamos que diseñe los puntos finales de autenticación de su aplicación para que su aplicación no exponga los códigos de autorización a otros recursos de la página.

Después de crear sus credenciales, descargue el archivo client_secret.json del API Console. Almacene de forma segura el archivo en una ubicación a la que solo pueda acceder su aplicación.

Identificar ámbitos de acceso

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

Antes de comenzar a implementar la autorización OAuth 2.0, le recomendamos que identifique los ámbitos a los que su aplicación necesitará permiso para acceder.

También recomendamos que su aplicación solicite acceso a los ámbitos de autorización a través de un proceso de autorización incremental , en el que su 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é su aplicación necesita el acceso que solicita.

El documento Ámbitos de la API de OAuth 2.0 contiene una lista completa de los ámbitos que puede utilizar para acceder a las API de Google.

Requisitos específicos del idioma

Para ejecutar cualquiera de los ejemplos de código de este documento, necesitará una cuenta de Google, acceso a Internet y un navegador web. Si está utilizando una de las bibliotecas cliente de API, consulte también los requisitos específicos del idioma a continuación.

PHP

Para ejecutar los ejemplos de código PHP en este documento, necesitará:

  • PHP 5.4 o superior con la interfaz de línea de comandos (CLI) y la extensión JSON instaladas.
  • La herramienta de gestión de dependencias de Composer .
  • La biblioteca cliente de las API de Google para PHP:

    php composer.phar require google/apiclient:^2.0

Pitón

Para ejecutar los ejemplos de código de Python en este documento, necesitará:

  • Python 2.6 o superior
  • La herramienta de gestión de paquetes pip .
  • Biblioteca cliente de las API de Google para Python:
    pip install --upgrade google-api-python-client
  • 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 marco de trabajo de la aplicación web Flask Python.
    pip install --upgrade flask
  • La biblioteca HTTP de requests .
    pip install --upgrade requests

Rubí

Para ejecutar los ejemplos de código Ruby en este documento, necesitará:

  • Ruby 2.2.2 o superior
  • La biblioteca cliente de las API de Google para Ruby:

    gem install google-api-client
  • El marco de la aplicación web Sinatra Ruby.

    gem install sinatra

HTTP / REST

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

Obtención de tokens de acceso de OAuth 2.0

Los siguientes pasos muestran cómo su aplicación interactúa con el servidor OAuth 2.0 de Google para obtener el consentimiento de un usuario para realizar una solicitud de API en su nombre. Su aplicación debe tener ese consentimiento antes de poder ejecutar una solicitud de API de Google que requiere la autorización del usuario.

La siguiente lista resume rápidamente estos pasos:

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

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

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

  • Si usa una biblioteca cliente de Google para la autenticación y autorización de OAuth 2.0, crea y configura un objeto que define estos parámetros.
  • Si llama directamente al punto final de Google OAuth 2.0, generará una URL y establecerá los parámetros en esa URL.

Las pestañas siguientes definen los parámetros de autorización admitidos para las aplicaciones del servidor web. Los ejemplos específicos del idioma también muestran cómo utilizar una biblioteca de 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 en la solicitud de autorización.

Ese objeto usa información de su archivo client_secret.json para identificar su aplicación. (Consulte Creación de credenciales de autorización para obtener más información sobre ese archivo). El objeto también identifica los ámbitos a los que su aplicación solicita permiso para acceder y la URL al extremo de autenticación de su aplicación, que manejará la respuesta del servidor OAuth 2.0 de Google. Finalmente, el código establece los access_type opcionales access_type e include_granted_scopes .

Por ejemplo, este código solicita acceso de solo lectura y sin conexión a 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" ensures that your application always receives a refresh token.
// If you are not using offline access, you can omit this.
$client->setApprovalPrompt("consent");
$client->setIncludeGrantedScopes(true);   // incremental auth

La solicitud especifica la siguiente información:

Parámetros
client_id Requerido

El ID de cliente de su aplicación. Puede encontrar este valor en el API Console Credentials page.

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

$client = new Google_Client();
$client->setAuthConfig('client_secret.json');
redirect_uri Requerido

Determina dónde el servidor de API redirige al usuario después de que el usuario 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 configuró en el API Console Credentials page de su cliente. Si este valor no coincide con un URI de redireccionamiento autorizado para el client_id proporcionado, obtendrá un error redirect_uri_mismatch .

Tenga en cuenta que el esquema http o https , el caso y la barra inclinada (' / ') deben coincidir.

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

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

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

Los ámbitos permiten que su aplicación solo solicite acceso a los recursos que necesita, al mismo tiempo que permite a los usuarios controlar la cantidad de acceso que otorgan a su aplicación. Por tanto, existe una relación inversa entre el número de alcances solicitados y la probabilidad de obtener el consentimiento del usuario.

Para establecer este valor en PHP, llame a la función addScope :

$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);

Recomendamos que su aplicación solicite acceso a los ámbitos de autorización en contexto siempre que sea posible. Al solicitar acceso a los datos del usuario en contexto, a través de una autorización incremental , ayuda a los usuarios a comprender más fácilmente por qué su aplicación necesita el acceso que solicita.

access_type Recomendado

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

Establezca el valor en offline de offline si su 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 indica al servidor de autorización de Google que devuelva un token de actualización y un token de acceso la primera vez que su aplicación intercambia un código de autorización por tokens.

Para establecer este valor en PHP, llame a la función setAccessType :

$client->setAccessType('offline');
state Recomendado

Especifica cualquier valor de cadena que utiliza su aplicación para mantener el estado entre su solicitud de autorización y la respuesta del servidor de autorización. El servidor devuelve el valor exacto que envía como un par name=value en el componente de consulta de URL ( ? ) De redirect_uri después de que el usuario consiente o deniegue la solicitud de acceso de su aplicación.

Puede usar este parámetro para varios propósitos, como dirigir al usuario al recurso correcto en su aplicación, enviar nonces y mitigar la falsificación de solicitudes entre sitios. Dado que se puede adivinar su redirect_uri , el uso de un valor de state puede aumentar su seguridad de que una conexión entrante es el resultado de una solicitud de autenticación. Si genera una cadena aleatoria o codifica el hash de una cookie u otro valor que captura el estado del cliente, puede validar la respuesta para asegurarse adicionalmente de que la solicitud y la respuesta se originaron en el mismo navegador, brindando protección contra ataques como entre sitios Solicitar falsificación. Consulte la documentación de OpenID Connect para ver un ejemplo de cómo crear y confirmar un token de state .

Para establecer este valor en PHP, llame a la función setState :

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

Permite que las aplicaciones utilicen una autorización incremental para solicitar acceso a ámbitos adicionales en contexto. Si establece el valor de este parámetro en true y se concede la solicitud de autorización, el nuevo token de acceso también cubrirá cualquier ámbito al que el usuario haya concedido previamente acceso a la aplicación. Consulte la sección de autorización incremental para ver ejemplos.

Para establecer este valor en PHP, llame a la función setIncludeGrantedScopes :

$client->setIncludeGrantedScopes(true);
login_hint Opcional

Si su aplicación sabe qué usuario está intentando autenticarse, puede utilizar este parámetro para proporcionar una pista al servidor de autenticación de Google. El servidor utiliza la sugerencia para simplificar el flujo de inicio de sesión ya sea rellenando previamente el campo de correo electrónico en el formulario de inicio de sesión o seleccionando la sesión de inicio de sesión múltiple adecuada.

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

Para establecer este valor en PHP, llame a la función setLoginHint :

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

Una lista de mensajes delimitados por espacios que distinguen entre mayúsculas y minúsculas para presentar al usuario. Si no especifica este parámetro, se le preguntará al usuario solo la primera vez que su proyecto solicite acceso. Consulte Solicitar un nuevo consentimiento para obtener más información.

Para establecer este valor en PHP, llame a la función setApprovalPrompt :

$client->setApprovalPrompt('consent');

Los posibles valores son:

none No muestre ninguna pantalla de autenticación o consentimiento. No debe especificarse con otros valores.
consent Solicitar al usuario su consentimiento.
select_account Solicitar al usuario que seleccione una cuenta.

Pitón

El siguiente fragmento de código usa el módulo google-auth-oauthlib.flow para construir la solicitud de autorización.

El código construye un objeto Flow , que identifica su aplicación utilizando información del archivo client_secret.json que descargó después de crear las credenciales de autorización . Ese objeto también identifica los ámbitos a los que su aplicación solicita permiso para acceder y la URL al extremo de autenticación de su aplicación, que manejará la respuesta del servidor OAuth 2.0 de Google. Finalmente, el código establece los access_type opcionales access_type e include_granted_scopes .

Por ejemplo, este código solicita acceso de solo lectura y sin conexión a 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 Requerido

El ID de cliente de su aplicación. Puede encontrar este valor en el API Console Credentials page.

En Python, llame al método from_client_secrets_file para recuperar el ID de cliente de un archivo client_secret.json . (También puede 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 Requerido

Determina dónde el servidor de API redirige al usuario después de que el usuario 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 configuró en el API Console Credentials page de su cliente. Si este valor no coincide con un URI de redireccionamiento autorizado para el client_id proporcionado, obtendrá un error redirect_uri_mismatch .

Tenga en cuenta que el esquema http o https , el caso y la barra inclinada (' / ') deben coincidir.

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

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

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

Los ámbitos permiten que su aplicación solo solicite acceso a los recursos que necesita, al mismo tiempo que permite a los usuarios controlar la cantidad de acceso que otorgan a su aplicación. Por tanto, existe una relación inversa entre el número de alcances solicitados y la probabilidad de obtener el consentimiento del usuario.

En Python, use el mismo método que usa para configurar el client_id para especificar la lista de alcances.

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

Recomendamos que su aplicación solicite acceso a los ámbitos de autorización en contexto siempre que sea posible. Al solicitar acceso a los datos del usuario en contexto, a través de una autorización incremental , ayuda a los usuarios a comprender más fácilmente por qué su aplicación necesita el acceso que solicita.

access_type Recomendado

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

Establezca el valor en offline de offline si su 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 indica al servidor de autorización de Google que devuelva un token de actualización y un token de acceso la primera vez que su aplicación intercambia un código de autorización por tokens.

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

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

Especifica cualquier valor de cadena que utiliza su aplicación para mantener el estado entre su solicitud de autorización y la respuesta del servidor de autorización. El servidor devuelve el valor exacto que envía como un par name=value en el componente de consulta de URL ( ? ) Del redirect_uri después de que el usuario consiente o deniegue la solicitud de acceso de su aplicación.

Puede usar este parámetro para varios propósitos, como dirigir al usuario al recurso correcto en su aplicación, enviar nonces y mitigar la falsificación de solicitudes entre sitios. Dado que se puede adivinar su redirect_uri , el uso de un valor de state puede aumentar su seguridad de que una conexión entrante es el resultado de una solicitud de autenticación. Si genera una cadena aleatoria o codifica el hash de una cookie u otro valor que captura el estado del cliente, puede validar la respuesta para asegurarse adicionalmente de que la solicitud y la respuesta se originaron en el mismo navegador, brindando protección contra ataques como entre sitios Solicitar falsificación. Consulte la documentación de OpenID Connect para ver un ejemplo de cómo crear y confirmar un token de state .

En Python, establecer el state de parámetros especificando state como un argumento de palabra clave cuando se llama al flow.authorization_url método:

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 utilicen una autorización incremental para solicitar acceso a ámbitos adicionales en contexto. Si establece el valor de este parámetro en true y se concede la solicitud de autorización, el nuevo token de acceso también cubrirá cualquier ámbito al que el usuario haya concedido previamente acceso a la aplicación. Consulte la sección de autorización incremental para ver ejemplos.

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

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

Si su aplicación sabe qué usuario está intentando autenticarse, puede utilizar este parámetro para proporcionar una pista al servidor de autenticación de Google. El servidor utiliza la sugerencia para simplificar el flujo de inicio de sesión ya sea rellenando previamente el campo de correo electrónico en el formulario de inicio de sesión o seleccionando la sesión de inicio de sesión múltiple adecuada.

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

En Python, configure el parámetro login_hint especificando login_hint como un argumento de palabra clave cuando llame 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 delimitados por espacios que distinguen entre mayúsculas y minúsculas para presentar al usuario. Si no especifica este parámetro, se le preguntará al usuario solo la primera vez que su proyecto solicite acceso. Consulte Solicitar un nuevo consentimiento para obtener más información.

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

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

Los posibles valores son:

none No muestre ninguna pantalla de autenticación o consentimiento. No debe especificarse con otros valores.
consent Solicitar al usuario su consentimiento.
select_account Solicitar al usuario que seleccione una cuenta.

Rubí

Utilice el archivo client_secrets.json que creó para configurar un objeto de cliente en su aplicación. Cuando configura un objeto de cliente, especifica los ámbitos a los que debe acceder su aplicación, junto con la URL al extremo de autenticación de su 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 Google Drive de un usuario:

require 'google/apis/drive_v2'
require 'google/api_client/client_secrets'

client_secrets = Google::APIClient::ClientSecrets.load
auth_client = client_secrets.to_authorization
auth_client.update!(
  :scope => 'https://www.googleapis.com/auth/drive.metadata.readonly',
  :redirect_uri => 'http://www.example.com/oauth2callback',
  :additional_parameters => {
    "access_type" => "offline",         # offline access
    "include_granted_scopes" => "true"  # incremental auth
  }
)

Tu aplicación usa el objeto de cliente para realizar operaciones de OAuth 2.0, como generar URL de solicitud de autorización y aplicar tokens de acceso a solicitudes HTTP.

HTTP / REST

El extremo OAuth 2.0 de Google se encuentra en https://accounts.google.com/o/oauth2/v2/auth . Este punto final es accesible solo a través de HTTPS. Se rechazan las conexiones HTTP simples.

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 Requerido

El ID de cliente de su aplicación. Puede encontrar este valor en el API Console Credentials page.

redirect_uri Requerido

Determina dónde el servidor de API redirige al usuario después de que el usuario 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 configuró en el API Console Credentials page de su cliente. Si este valor no coincide con un URI de redireccionamiento autorizado para el client_id proporcionado, obtendrá un error redirect_uri_mismatch .

Tenga en cuenta que el esquema http o https , el caso y la barra inclinada (' / ') deben coincidir.

response_type Requerido

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

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

scope Requerido

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

Los ámbitos permiten que su aplicación solo solicite acceso a los recursos que necesita, al mismo tiempo que permite a los usuarios controlar la cantidad de acceso que otorgan a su aplicación. Por tanto, existe una relación inversa entre el número de alcances solicitados y la probabilidad de obtener el consentimiento del usuario.

Recomendamos que su aplicación solicite acceso a los ámbitos de autorización en contexto siempre que sea posible. Al solicitar acceso a los datos del usuario en contexto, a través de una autorización incremental , ayuda a los usuarios a comprender más fácilmente por qué su aplicación necesita el acceso que solicita.

access_type Recomendado

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

Establezca el valor en offline de offline si su 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 indica al servidor de autorización de Google que devuelva un token de actualización y un token de acceso la primera vez que su aplicación intercambia un código de autorización por tokens.

state Recomendado

Especifica cualquier valor de cadena que utiliza su aplicación para mantener el estado entre su solicitud de autorización y la respuesta del servidor de autorización. El servidor devuelve el valor exacto que envía como un par name=value en el componente de consulta de URL ( ? ) De redirect_uri después de que el usuario consiente o deniegue la solicitud de acceso de su aplicación.

Puede usar este parámetro para varios propósitos, como dirigir al usuario al recurso correcto en su aplicación, enviar nonces y mitigar la falsificación de solicitudes entre sitios. Dado que se puede adivinar su redirect_uri , el uso de un valor de state puede aumentar su seguridad de que una conexión entrante es el resultado de una solicitud de autenticación. Si genera una cadena aleatoria o codifica el hash de una cookie u otro valor que captura el estado del cliente, puede validar la respuesta para asegurarse adicionalmente de que la solicitud y la respuesta se originaron en el mismo navegador, brindando protección contra ataques como entre sitios Solicitar falsificación. Consulte la documentación de OpenID Connect para ver un ejemplo de cómo crear y confirmar un token de state .

include_granted_scopes Opcional

Permite que las aplicaciones utilicen una autorización incremental para solicitar acceso a ámbitos adicionales en contexto. Si establece el valor de este parámetro en true y se concede la solicitud de autorización, el nuevo token de acceso también cubrirá cualquier ámbito al que el usuario haya concedido previamente acceso a la aplicación. Consulte la sección de autorización incremental para ver ejemplos.

login_hint Opcional

Si su aplicación sabe qué usuario está intentando autenticarse, puede utilizar este parámetro para proporcionar una pista al servidor de autenticación de Google. El servidor utiliza la sugerencia para simplificar el flujo de inicio de sesión ya sea rellenando previamente el campo de correo electrónico en el formulario de inicio de sesión o seleccionando la sesión de inicio de sesión múltiple adecuada.

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

prompt Opcional

Una lista de mensajes delimitados por espacios que distinguen entre mayúsculas y minúsculas para presentar al usuario. Si no especifica este parámetro, se le preguntará al usuario solo la primera vez que su proyecto solicite acceso. Consulte Solicitar un nuevo consentimiento para obtener más información.

Los posibles valores son:

none No muestre ninguna pantalla de autenticación o consentimiento. No debe especificarse con otros valores.
consent Solicitar al usuario su consentimiento.
select_account Solicitar al usuario que seleccione una cuenta.

Paso 2: Redirigir al servidor OAuth 2.0 de Google

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

PHP

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

Pitón

Este ejemplo muestra cómo redirigir al usuario a la URL de autorización utilizando el marco de la aplicación web Flask:

return flask.redirect(authorization_url)

Rubí

  1. Genere una URL para solicitar acceso desde el servidor OAuth 2.0 de Google:
    auth_uri = auth_client.authorization_uri.to_s
  2. Redirigir al usuario a auth_uri .

HTTP / REST

Ejemplo de redireccionamiento al servidor de autorización de Google

A continuación se muestra un ejemplo de URL, con saltos de línea y espacios para facilitar la lectura.

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, redirija al usuario a ella.

El servidor OAuth 2.0 de Google autentica al usuario y obtiene el consentimiento del usuario para que su aplicación acceda a los ámbitos solicitados. La respuesta se envía de vuelta a su aplicación utilizando la URL de redireccionamiento que especificó.

Paso 3: Google solicita el consentimiento del usuario

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

Su aplicación no necesita hacer nada en esta etapa, ya que espera la respuesta del servidor OAuth 2.0 de Google que indica si se le otorgó acceso. Esa respuesta se explica en el siguiente paso.

Paso 4: Manejar la respuesta del servidor OAuth 2.0

El servidor OAuth 2.0 responde a la solicitud de acceso de su aplicación mediante el uso de la URL especificada en la solicitud.

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

Una 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 OAuth 2.0

Puede probar este flujo haciendo clic en la siguiente URL de muestra, que solicita acceso de solo lectura para ver los metadatos de los archivos en su 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, debe ser redirigido a http://localhost/oauth2callback , que probablemente producirá un error 404 NOT FOUND menos que su máquina local http://localhost/oauth2callback un archivo en esa dirección. El siguiente paso proporciona más detalles sobre la información devuelta en el URI cuando se redirige al usuario a su aplicación.

Paso 5: Código de autorización de intercambio para tokens de acceso y actualización

Una vez que el servidor web recibe el código de autorización, puede cambiar el código de autorización por un token de acceso.

PHP

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

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

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

$access_token = $client->getAccessToken();

Pitón

En su página de devolución de llamada, use la biblioteca google-auth para verificar la respuesta del servidor de autorización. Luego, use 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}

Rubí

¡Para intercambiar un código de autorización por un token de acceso, use el fetch_access_token! método:

auth_client.code = auth_code
auth_client.fetch_access_token!

HTTP / REST

Para intercambiar un código de autorización por un token de acceso, llame al punto final https://oauth2.googleapis.com/token y configure los siguientes parámetros:

Campos
client_id El ID de cliente obtenido del API Console Credentials page.
client_secret El secreto del cliente obtenido del API Console Credentials page.
code El código de autorización devuelto por la solicitud inicial.
grant_type Como se define en la especificación OAuth 2.0 , el valor de este campo debe establecerse en authorization_code .
redirect_uri Uno de los URI de redireccionamiento enumerados para su proyecto en API Console Credentials page para el client_id dado.

El siguiente fragmento muestra una solicitud de muestra:

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

Google responde a esta solicitud devolviendo un objeto JSON que contiene un token de acceso de corta duración y un token de actualización. Tenga en cuenta que el token de actualización solo se devuelve si su 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 El token que envía su aplicación para autorizar una solicitud de API de Google.
expires_in La vida útil restante del token de acceso en segundos.
refresh_token Un token que puede usar para obtener un nuevo token de acceso. Los tokens de actualización son válidos hasta que el usuario revoca el acceso. Nuevamente, este campo solo está presente en esta respuesta si establece el parámetro access_type en offline en la solicitud inicial al servidor de autorización de Google.
scope Los alcances de acceso otorgados por el access_token expresados ​​como una lista de cadenas que access_token mayúsculas y minúsculas y delimitadas por espacios.
token_type El tipo de token devuelto. En este momento, el valor de este campo siempre se establece en Bearer .

El siguiente fragmento 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"
}

Llamar a las API de Google

PHP

Utilice el token de acceso para llamar a las API de Google completando los siguientes pasos:

  1. Si es necesario aplicar un token de acceso a una nueva Google_Client objeto, por ejemplo, si se ha almacenado el token de acceso de un usuario sesión de utilizar el setAccessToken método:
    $client->setAccessToken($access_token);
  2. Cree un objeto de servicio para la API que desea llamar. Usted crea un objeto de servicio proporcionando un objeto Google_Client autorizado al constructor de la API que desea llamar. Por ejemplo, para llamar a la API de Drive:
    $drive = new Google_Service_Drive($client);
  3. Realice solicitudes al servicio API utilizando la interfaz proporcionada por el objeto de servicio . Por ejemplo, para enumerar los archivos en Google Drive del usuario autenticado:
    $files = $drive->files->listFiles(array())->getItems();

Pitón

Después de obtener un token de acceso, su aplicación puede usar ese token para autorizar solicitudes de API en nombre de una cuenta de usuario o de servicio determinada. Use las credenciales de autorización específicas del usuario para crear un objeto de servicio para la API que desea llamar y luego use ese objeto para realizar solicitudes de API autorizadas.

  1. Cree un objeto de servicio para la API que desea llamar. Para crear un objeto de servicio, llame al googleapiclient.discovery de build 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 2 de la API de Drive:
    from googleapiclient.discovery import build
    
    drive = build('drive', 'v2', credentials=credentials)
  2. Realice solicitudes al servicio API utilizando la interfaz proporcionada por el objeto de servicio . Por ejemplo, para enumerar los archivos en Google Drive del usuario autenticado:
    files = drive.files().list().execute()

Rubí

Utilice el objeto auth_client para llamar a las API de Google completando los siguientes pasos:

  1. Cree un objeto de servicio para la API que desea llamar. Por ejemplo, para llamar a la versión 2 de la API de Drive:
    drive = Google::Apis::DriveV2::DriveService.new
  2. Configure las credenciales en el servicio:
    drive.authorization = auth_client
  3. Realice solicitudes al servicio API utilizando la interfaz proporcionada por el objeto de servicio . Por ejemplo, para enumerar los archivos en Google Drive del usuario autenticado:
    files = drive.list_files

Alternativamente, la autorización se puede proporcionar por método proporcionando el parámetro de options a un método:

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

HTTP / REST

Una vez que su aplicación obtiene un token de acceso, puede usar el token para realizar llamadas a una API de Google en nombre de una cuenta de usuario determinada si se han otorgado los alcances de acceso requeridos por la API. Para hacer esto, incluya el token de acceso en una solicitud a la API incluyendo un parámetro de consulta access_token o un valor de Bearer encabezado HTTP de Authorization . Cuando sea posible, es preferible el encabezado HTTP, porque las cadenas de consulta tienden a ser visibles en los registros del servidor. En la mayoría de los casos, puede utilizar una biblioteca cliente para configurar sus llamadas a las API de Google (por ejemplo, al llamar a la API de archivos de Drive ).

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

Ejemplos de HTTP GET

Una llamada al drive.files final drive.files (la API de archivos de Drive) utilizando el encabezado HTTP Authorization: Bearer puede tener el siguiente aspecto. Tenga en cuenta que debe especificar su propio token de acceso:

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

Aquí hay una llamada a la misma API para el usuario autenticado usando el parámetro de cadena de consulta access_token :

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

ejemplos de curl

Puede probar estos comandos con la aplicación de línea de comandos curl . Aquí hay un ejemplo que usa la opción de encabezado HTTP (preferido):

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

O, alternativamente, la opción de parámetro de cadena de consulta:

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

Ejemplo completo

El siguiente ejemplo imprime una lista de archivos con formato JSON en Google Drive de un usuario después de que el usuario se autentica y da su consentimiento para que la aplicación acceda a los metadatos de Drive del usuario.

PHP

Para ejecutar este ejemplo:

  1. En API Console, agregue la URL de la máquina local a la lista de URL de redireccionamiento. Por ejemplo, agregue http://localhost:8080 .
  2. Cree un nuevo directorio y cámbielo. Por ejemplo:
    mkdir ~/php-oauth2-example
    cd ~/php-oauth2-example
  3. Instale la biblioteca cliente de la API de Google para PHP con Composer :
    composer require google/apiclient:^2.0
  4. Cree los archivos index.php y oauth2callback.php con el contenido a continuación.
  5. Ejecute el ejemplo con un servidor web configurado para servir PHP. Si usa PHP 5.4 o más reciente, puede 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));
}

Pitón

Este ejemplo utiliza el marco Flask . Ejecuta una aplicación web en http://localhost:8080 que le permite probar el flujo de OAuth 2.0. Si va a esa URL, debería ver cuatro enlaces:

  • Probar una solicitud de API: este enlace apunta a una página que intenta ejecutar una solicitud de API de muestra. Si es necesario, inicia el flujo de autorización. Si tiene éxito, la página muestra la respuesta de la API.
  • Pruebe el flujo de autorización directamente: este enlace apunta a una página que intenta enviar al usuario a través del flujo de autorización . La aplicación solicita permiso para enviar solicitudes de API autorizadas en nombre del usuario.
  • Revocar las credenciales actuales: este enlace apunta a una página que revoca los permisos que el usuario ya ha concedido a la aplicación.
  • Borrar credenciales de sesión de Flask: este enlace borra las credenciales de autorización almacenadas en la sesión de Flask. Esto le permite ver qué sucedería si un usuario que ya había otorgado permiso a su aplicación intentara ejecutar una solicitud de API en una nueva sesión. También le permite ver la respuesta de la API que su aplicación obtendría si un usuario hubiera revocado los permisos otorgados a su aplicación, y su aplicación 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)

Rubí

Este ejemplo utiliza el marco de Sinatra .

require 'google/apis/drive_v2'
require 'google/api_client/client_secrets'
require 'json'
require 'sinatra'

enable :sessions
set :session_secret, 'setme'

get '/' do
  unless session.has_key?(:credentials)
    redirect to('/oauth2callback')
  end
  client_opts = JSON.parse(session[:credentials])
  auth_client = Signet::OAuth2::Client.new(client_opts)
  drive = Google::Apis::DriveV2::DriveService.new
  files = drive.list_files(options: { authorization: auth_client })
  "<pre>#{JSON.pretty_generate(files.to_h)}</pre>"
end

get '/oauth2callback' do
  client_secrets = Google::APIClient::ClientSecrets.load
  auth_client = client_secrets.to_authorization
  auth_client.update!(
    :scope => 'https://www.googleapis.com/auth/drive.metadata.readonly',
    :redirect_uri => url('/oauth2callback'))
  if request['code'] == nil
    auth_uri = auth_client.authorization_uri.to_s
    redirect to(auth_uri)
  else
    auth_client.code = request['code']
    auth_client.fetch_access_token!
    auth_client.client_secret = nil
    session[:credentials] = auth_client.to_json
    redirect to('/')
  end
end

HTTP / REST

Este ejemplo de Python utiliza el marco Flask y la biblioteca de solicitudes para demostrar el flujo web de OAuth 2.0. Recomendamos utilizar la biblioteca cliente de la API de Google para Python para este flujo. (El ejemplo en la pestaña Python 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()

Redirigir las reglas de validación de URI

Google aplica las siguientes reglas de validación para redirigir los URI a fin de ayudar a los desarrolladores a mantener seguras sus aplicaciones. Sus URI de redireccionamiento deben cumplir con estas reglas. Consulte la sección 3 de RFC 3986 para obtener la definición de dominio, host, ruta, consulta, esquema e información de usuario, que se menciona a continuación.

Reglas de validación
Esquema

Los URI deben usar el esquema HTTPS, no HTTP simple.

Anfitrión

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 no pueden contener dominios de acortadores de URL (por ejemplo, goo.gl ) a menos que la aplicación sea propietaria del dominio. Además, si una aplicación que posee un dominio más corto elige redirigir a ese dominio, ese URI de redireccionamiento debe contener “/google-callback/” en su ruta o terminar con “/google-callback” .
  • Información de usuario

    Los URI de redireccionamiento no pueden contener el subcomponente de información de usuario.

    Camino

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

    Consulta

    Los URI de redireccionamiento no pueden contener redireccionamientos abiertos .

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

    Autorización incremental

    En el protocolo OAuth 2.0, su aplicación solicita autorización para acceder a los recursos, que se identifican por ámbitos. Se considera una mejor práctica para la experiencia del usuario solicitar autorización para los recursos en el momento en que los necesite. Para habilitar esa práctica, el servidor de autorización de Google admite autorización incremental. Esta función le permite solicitar ámbitos según sean necesarios y, si el usuario concede permiso para el nuevo ámbito, devuelve un código de autorización que puede intercambiarse por un token que contiene todos los ámbitos que el usuario ha concedido al proyecto.

    Por ejemplo, una aplicación que permite a las personas probar pistas de música y crear mezclas puede necesitar muy pocos recursos en el momento del inicio de sesión, tal vez nada más que el nombre de la persona que inicia sesión. Sin embargo, guardar una mezcla completa requeriría acceso a su Google Drive. . A la mayoría de las personas les resultaría natural si solo se les pidiera acceso a su Google Drive en el momento en que la aplicación realmente lo necesitaba.

    En este caso, en el momento del inicio de sesión, la aplicación puede solicitar el openid y los ámbitos de profile para realizar un inicio de sesión básico y, luego, solicitar el https://www.googleapis.com/auth/drive.file ámbito en el momento la primera solicitud para guardar una mezcla.

    Para implementar la autorización incremental, complete el flujo normal para solicitar un token de acceso, pero asegúrese de que la solicitud de autorización incluya alcances otorgados previamente. Este enfoque permite que su aplicación evite tener que administrar múltiples tokens de acceso.

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

    • El token se puede utilizar para acceder a los recursos correspondientes a cualquiera de los ámbitos incluidos en la nueva autorización combinada.
    • Cuando usa el token de actualización para la autorización combinada para obtener un token de acceso, el token de acceso 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 las concesiones se solicitaron a diferentes clientes. Por ejemplo, si un usuario otorgó acceso a un alcance utilizando el cliente de escritorio de una aplicación y luego otorgó otro alcance a la misma aplicación a través de un cliente móvil, la autorización combinada incluiría ambos alcances.
    • Si revoca un token que representa una autorización combinada, el acceso a todos los alcances de esa autorización en nombre del usuario asociado se revoca simultáneamente.

    Los ejemplos de código específico del idioma en el Paso 1: configurar los parámetros de autorización y la URL de redireccionamiento HTTP / REST de muestra en el Paso 2: Redirigir al servidor OAuth 2.0 de Google utilizan la autorización incremental. Los ejemplos de código a continuación también muestran el código que debe agregar para usar la autorización incremental.

    PHP

    $client->setIncludeGrantedScopes(true);

    Pitón

    En Python, establezca el argumento de la palabra clave include_granted_scopes en true para asegurarse de que una solicitud de autorización incluya alcances otorgados previamente. Es muy posible que include_granted_scopes no sea el único argumento de palabra clave que establezca, 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')

    Rubí

    auth_client.update!(
      :additional_parameters => {"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

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

    Los tokens de acceso expiran periódicamente y se convierten en credenciales no válidas para una solicitud de API relacionada. Puede actualizar un token de acceso sin pedir permiso al usuario (incluso cuando el usuario no está presente) si solicitó acceso sin conexión a los ámbitos asociados con el token.

    • Si utiliza una biblioteca cliente de API de Google, el objeto cliente actualiza el token de acceso según sea necesario siempre que configure ese objeto para el acceso sin conexión.
    • Si no está utilizando una biblioteca de cliente, debe establecer el parámetro de consulta HTTP access_type como offline al redirigir al usuario al servidor OAuth 2.0 de Google . En ese caso, el servidor de autorización de Google devuelve un token de actualización cuando intercambia un código de autorización por un token de acceso. Luego, si el token de acceso caduca (o en cualquier otro momento), puede usar un token de actualización para obtener un nuevo token de acceso.

    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 aplicación que realiza servicios de respaldo 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 llama en online .

    Server-side web applications, installed applications, and devices all obtain refresh tokens during the authorization process. Refresh tokens are not typically used in client-side (JavaScript) web applications.

    PHP

    If your application needs offline access to a Google API, set the API client's access type to offline :

    $client->setAccessType("offline");

    After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.

    Python

    In Python, set the access_type keyword argument to offline to ensure that you will be able to refresh the access token without having to re-prompt the user for permission. It is very possible that access_type will not be the only keyword argument that you set, as shown in the example below.

    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')

    After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.

    Ruby

    If your application needs offline access to a Google API, set the API client's access type to offline :

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

    After a user grants offline access to the requested scopes, you can continue to use the API client to access Google APIs on the user's behalf when the user is offline. The client object will refresh the access token as needed.

    HTTP/REST

    Para actualizar un token de acceso, su aplicación envía una POST HTTPS POST 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 del API Console.
    client_secret El secreto de cliente obtenido del API Console.
    grant_type Como se define en la especificación OAuth 2.0 , el valor de este campo debe establecerse en refresh_token .
    refresh_token El token de actualización devuelto por el intercambio de códigos 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 devuelve un objeto JSON que contiene un nuevo token de acceso. El siguiente fragmento muestra una respuesta de muestra:

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

    Tenga en cuenta que existen límites en la cantidad de tokens de actualización que se emitirán; un límite por combinación de cliente / usuario y otro por usuario en todos los clientes. Debe guardar los tokens de actualización en un almacenamiento a largo plazo y continuar usándolos mientras sigan siendo válidos. Si su aplicación solicita demasiados tokens de actualización, puede encontrarse con estos límites, en cuyo caso los tokens de actualización más antiguos dejarán de funcionar.

    Revocar una ficha

    En algunos casos, un usuario puede desear revocar el acceso otorgado a una aplicación. Un usuario puede revocar el acceso visitando Configuración de la cuenta . Consulte la sección Eliminar el acceso a sitios o aplicaciones de Sitios y aplicaciones de terceros con acceso al documento de soporte de su cuenta para obtener más información.

    También es posible que una aplicación revoque mediante programación el acceso que se le ha otorgado. La revocación programática es importante en los casos en que un usuario cancela su suscripción, elimina una aplicación o los recursos de API requeridos por una aplicación han cambiado significativamente. En otras palabras, parte del proceso de eliminación puede incluir una solicitud de API para garantizar que se eliminen los permisos otorgados previamente a la aplicación.

    PHP

    To programmatically revoke a token, call revokeToken() :

    $client->revokeToken();

    Python

    To programmatically revoke a token, make a request to https://oauth2.googleapis.com/revoke that includes the token as a parameter and sets the Content-Type header:

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

    Ruby

    To programmatically revoke a token, make an HTTP request to the oauth2.revoke endpoint:

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

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

    If the revocation is successfully processed, then the status code of the response is 200 . For error conditions, a status code 400 is returned along with an error code.

    HTTP/REST

    Para revocar un token mediante programación, su 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 un token 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 condiciones de error, se devuelve un código de estado HTTP 400 junto con un código de error.