Se usó la API de Cloud Translation para traducir esta página.
Switch to English

OAuth 2.0 para aplicaciones web del lado del cliente

Este documento explica cómo implementar la autorización OAuth 2.0 para acceder a las API de Google desde una aplicación web JavaScript. 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 se denomina flujo de concesión implícito . Está diseñado para aplicaciones que acceden a las API solo mientras el usuario está presente en la aplicación. Estas aplicaciones no pueden almacenar información confidencial.

En este flujo, su aplicación abre una URL de Google que usa parámetros de consulta para identificar su aplicación y el tipo de acceso a la API que la aplicación requiere. Puede abrir la URL en la ventana actual del navegador o en una ventana emergente. El usuario puede autenticarse con Google y otorgar los permisos solicitados. Luego, Google redirige al usuario a su aplicación. El redireccionamiento incluye un token de acceso, que su aplicación verifica y luego usa para realizar solicitudes de API.

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 y luego haga clic en el botón Habilitar .
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

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. Completa el formulario. Las aplicaciones que utilizan JavaScript para realizar solicitudes de API de Google autorizadas deben especificar los orígenes autorizados de JavaScript . Los orígenes identifican los dominios desde los cuales su aplicación puede enviar solicitudes al servidor OAuth 2.0. Estos orígenes deben cumplir con las reglas de validación de Google .

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.

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.

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 nombre del usuario. Su aplicación debe tener ese consentimiento antes de poder ejecutar una solicitud de API de Google que requiere la autorización del usuario.

Paso 1: configurar el objeto de cliente

Si utiliza la biblioteca cliente de las API de Google para JavaScript para manejar el flujo de OAuth 2.0, su primer paso es configurar los objetos gapi.auth2 y gapi.client . Estos objetos permiten que su aplicación obtenga la autorización del usuario y realice solicitudes de API autorizadas.

El objeto de cliente identifica los ámbitos a los que su aplicación solicita permiso para acceder. Estos valores informan la pantalla de consentimiento que Google muestra al usuario.

Biblioteca cliente JS

La biblioteca cliente de JavaScript simplifica numerosos aspectos del proceso de autorización:

  1. Crea la URL de redireccionamiento para el servidor de autorización de Google y proporciona un método para dirigir al usuario a esa URL.
  2. Maneja la redirección desde ese servidor a su aplicación.
  3. Valida el token de acceso devuelto por el servidor de autorización.
  4. Almacena el token de acceso que el servidor de autorización envía a su aplicación y lo recupera cuando su aplicación posteriormente realiza llamadas API autorizadas.

El siguiente fragmento de código es un extracto del ejemplo completo que se muestra más adelante en este documento. Este código inicializa el objeto gapi.client , que su aplicación usaría más tarde para realizar llamadas a la API. Cuando se crea gapi.auth2 objeto, también se inicializa el objeto gapi.auth2 , que su aplicación usa para verificar y monitorear el estado de autorización del usuario.

La llamada a gapi.client.init especifica los siguientes campos:

  • Los valores apiKey y clientId especifican las credenciales de autorización de su aplicación. Como se discutió en la sección de creación de credenciales de autorización , estos valores se pueden obtener en el API Console. Tenga en cuenta que el clientId es necesario si su aplicación realiza solicitudes de API autorizadas. Las aplicaciones que solo realizan solicitudes no autorizadas solo pueden especificar una clave API.
  • El campo de scope especifica una lista delimitada por espacios de alcances de acceso que corresponden a 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.

    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.

  • El campo discoveryDocs identifica una lista de documentos de descubrimiento de API que utiliza su aplicación. Un documento de Discovery describe la superficie de una API, incluidos sus esquemas de recursos, y la biblioteca cliente de JavaScript usa esa información para generar métodos que las aplicaciones pueden usar. En este ejemplo, el código recupera el documento de descubrimiento para la versión 3 de la API de Google Drive.

Una gapi.client.init completa la llamada a gapi.client.init , el código establece la variable GoogleAuth para identificar el objeto de autenticación de Google. Por último, el código establece un oyente que llama a una función cuando cambia el estado de inicio de sesión del usuario. (Esa función no está definida en el fragmento).

var GoogleAuth; // Google Auth object.
function initClient() {
  gapi.client.init({
      'apiKey': 'YOUR_API_KEY',
      'clientId': 'YOUR_CLIENT_ID',
      'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
      'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/drive/v3/rest']
  }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);
  });
}

Extremos de OAuth 2.0

Si accede directamente a los puntos finales de OAuth 2.0, puede continuar con el siguiente paso.

Paso 2: Redirigir al servidor OAuth 2.0 de Google

Para solicitar permiso para acceder a los datos de un usuario, redirigir al usuario al servidor OAuth 2.0 de Google.

Biblioteca cliente JS

Llame al método GoogleAuth.signIn() para dirigir al usuario al servidor de autorización de Google.

GoogleAuth.signIn();

En la práctica, su aplicación puede establecer un valor booleano para determinar si debe llamar al método signIn() antes de intentar realizar una llamada a la API.

El fragmento de código a continuación demuestra cómo iniciaría el flujo de autorización del usuario. Tenga en cuenta los siguientes puntos sobre el fragmento:

  • El objeto GoogleAuth que se hace referencia en el código es el mismo que la variable global definida en el fragmento de código en el paso 1 .

  • La función updateSigninStatus es un oyente que escucha los cambios en el estado de autorización del usuario. Su función como oyente también se definió en el fragmento de código en el paso 1:
    GoogleAuth.isSignedIn.listen(updateSigninStatus);
  • El fragmento define dos variables globales adicionales:

    • isAuthorized es una variable booleana que indica si el usuario ya isAuthorized . Este valor se puede establecer cuando la aplicación se carga y se actualiza si el usuario isAuthorized o sale de la aplicación.

      En este fragmento, la función sendAuthorizedApiRequest verifica el valor de la variable para determinar si la aplicación debe intentar una solicitud de API que requiera autorización o solicitar al usuario que autorice la aplicación.

    • currentApiRequest es un objeto que almacena detalles sobre la última solicitud de API que intentó el usuario. El valor del objeto se establece cuando la aplicación llama a la función sendAuthorizedApiRequest .

      Si el usuario ha autorizado la aplicación, la solicitud se ejecuta de inmediato. De lo contrario, la función redirige al usuario para que updateSignInStatus sesión. Después de que el usuario updateSignInStatus , la función sendAuthorizedApiRequest llama a sendAuthorizedApiRequest , pasando la misma solicitud que se intentó antes de que comenzara el flujo de autorización.

var isAuthorized;
var currentApiRequest;

/**
 * Store the request details. Then check to determine whether the user
 * has authorized the application.
 *   - If the user has granted access, make the API request.
 *   - If the user has not granted access, initiate the sign-in flow.
 */
function sendAuthorizedApiRequest(requestDetails) {
  currentApiRequest = requestDetails;
  if (isAuthorized) {
    // Make API request
    // gapi.client.request(requestDetails)

    // Reset currentApiRequest variable.
    currentApiRequest = {};
  } else {
    GoogleAuth.signIn();
  }
}

/**
 * Listener called when user completes auth flow. If the currentApiRequest
 * variable is set, then the user was prompted to authorize the application
 * before the request executed. In that case, proceed with that API request.
 */
function updateSigninStatus(isSignedIn) {
  if (isSignedIn) {
    isAuthorized = true;
    if (currentApiRequest) {
      sendAuthorizedApiRequest(currentApiRequest);
    }
  } else {
    isAuthorized = false;
  }
}

Extremos de OAuth 2.0

Genere una URL para solicitar acceso desde el punto final OAuth 2.0 de Google en https://accounts.google.com/o/oauth2/v2/auth . Se puede acceder a este punto final 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

Las aplicaciones de JavaScript deben establecer el valor del parámetro en token . Este valor indica al servidor de autorización de Google que devuelva el token de acceso como un par name=value en el identificador de fragmento del URI ( # ) al que se redirige al usuario después de completar el proceso de autorización.

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.

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 identificador de fragmento de URL ( # ) de redirect_uri después de que el usuario consiente o rechace 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 , usar 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.

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&
 include_granted_scopes=true&
 response_type=token&
 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.

Código de muestra de JavaScript

El siguiente fragmento de JavaScript muestra cómo iniciar el flujo de autorización en JavaScript sin utilizar la biblioteca cliente de las API de Google para JavaScript. Dado que este extremo de OAuth 2.0 no admite el uso compartido de recursos de origen cruzado (CORS), el fragmento crea un formulario que abre la solicitud a ese extremo.

/*
 * Create form to request access token from Google's OAuth 2.0 server.
 */
function oauthSignIn() {
  // Google's OAuth 2.0 endpoint for requesting an access token
  var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

  // Create <form> element to submit parameters to OAuth 2.0 endpoint.
  var form = document.createElement('form');
  form.setAttribute('method', 'GET'); // Send as a GET request.
  form.setAttribute('action', oauth2Endpoint);

  // Parameters to pass to OAuth 2.0 endpoint.
  var params = {'client_id': 'YOUR_CLIENT_ID',
                'redirect_uri': 'YOUR_REDIRECT_URI',
                'response_type': 'token',
                'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                'include_granted_scopes': 'true',
                'state': 'pass-through value'};

  // Add form parameters as hidden input values.
  for (var p in params) {
    var input = document.createElement('input');
    input.setAttribute('type', 'hidden');
    input.setAttribute('name', p);
    input.setAttribute('value', params[p]);
    form.appendChild(input);
  }

  // Add form to page and submit it to open the OAuth 2.0 endpoint.
  document.body.appendChild(form);
  form.submit();
}

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 la 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

Biblioteca cliente JS

La biblioteca cliente de JavaScript maneja la respuesta del servidor de autorización de Google. Si configura un oyente para monitorear los cambios en el estado de inicio de sesión del usuario actual, esa función se llama cuando el usuario otorga el acceso solicitado a la aplicación.

Extremos de OAuth 2.0

El servidor OAuth 2.0 envía una respuesta al redirect_uri especificado en su solicitud de token de acceso.

Si el usuario aprueba la solicitud, la respuesta contiene un token de acceso. Si el usuario no aprueba la solicitud, la respuesta contiene un mensaje de error. El token de acceso o el mensaje de error se devuelve en el fragmento hash del URI de redireccionamiento, como se muestra a continuación:

  • Una respuesta de token de acceso:

    https://oauth2.example.com/callback#access_token=4/P7q7W91&token_type=Bearer&expires_in=3600

    Además del parámetro access_token , la cadena de fragmentos también contiene el parámetro token_type , que siempre se establece en Bearer , y el parámetro expires_in , que especifica la vida útil del token, en segundos. Si el parámetro de state se especificó en la solicitud del token de acceso, su valor también se incluye en la respuesta.

  • Una respuesta de error:
    https://oauth2.example.com/callback#error=access_denied

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&
 include_granted_scopes=true&
 response_type=token&
 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 le redirigirá a http://localhost/oauth2callback . Esa URL producirá un error 404 NOT FOUND menos que su máquina local entregue 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.

Llamar a las API de Google

Biblioteca cliente JS

Una vez que su aplicación obtiene un token de acceso, puede usar la biblioteca cliente de JavaScript para realizar solicitudes de API en nombre del usuario. La biblioteca cliente administra el token de acceso por usted, y no necesita hacer nada especial para enviarlo en la solicitud.

La biblioteca cliente admite dos formas de llamar a métodos API. Si ha cargado un documento de descubrimiento, la API definirá funciones específicas del método por usted. También puede utilizar la función gapi.client.request para llamar a un método API. Los siguientes dos fragmentos demuestran estas opciones para el método about.get la API de about.get .

// Example 1: Use method-specific function
var request = gapi.client.drive.about.get({'fields': 'user'});

// Execute the API request.
request.execute(function(response) {
  console.log(response);
});


// Example 2: Use gapi.client.request(args) function
var request = gapi.client.request({
  'method': 'GET',
  'path': '/drive/v3/about',
  'params': {'fields': 'user'}
});
// Execute the API request.
request.execute(function(response) {
  console.log(response);
});

Extremos de OAuth 2.0

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

Código de muestra de JavaScript

El siguiente fragmento de código demuestra cómo utilizar CORS (uso compartido de recursos de origen cruzado) para enviar una solicitud a una API de Google. Este ejemplo no utiliza la biblioteca cliente de las API de Google para JavaScript. Sin embargo, incluso si no está utilizando la biblioteca cliente, la guía de soporte CORS en la documentación de esa biblioteca probablemente lo ayudará a comprender mejor estas solicitudes.

En este fragmento de código, la variable access_token representa el token que ha obtenido para realizar solicitudes de API en nombre del usuario autorizado. El ejemplo completo demuestra cómo almacenar ese token en el almacenamiento local del navegador y recuperarlo al realizar una solicitud de API.

var xhr = new XMLHttpRequest();
xhr.open('GET',
    'https://www.googleapis.com/drive/v3/about?fields=user&' +
    'access_token=' + params['access_token']);
xhr.onreadystatechange = function (e) {
  console.log(xhr.response);
};
xhr.send(null);

Ejemplo completo

Biblioteca cliente JS

Demostración de código de muestra

Esta sección contiene una demostración funcional del ejemplo de código que sigue para demostrar cómo se comporta el código en una aplicación real. Una vez que autorice la aplicación, se incluirá entre las aplicaciones conectadas a su cuenta de Google . La aplicación se llama OAuth 2.0 Demo para Google API Docs . Del mismo modo, si revoca el acceso y actualiza esa página, esa aplicación ya no aparecerá en la lista.

Tenga en cuenta que esta aplicación solicita acceso al alcance https://www.googleapis.com/auth/drive.metadata.readonly . El acceso se solicita solo para demostrar cómo iniciar el flujo de OAuth 2.0 en una aplicación de JavaScript. Esta aplicación no realiza ninguna solicitud de API.

Código de muestra de JavaScript

Como se muestra arriba, esta muestra de código es para una página (una aplicación) que carga la biblioteca de cliente de las API de Google para JavaScript e inicia el flujo de OAuth 2.0. La página muestra:

  • Un botón que permite al usuario iniciar sesión en la aplicación. Si el usuario no ha autorizado previamente la aplicación, la aplicación inicia el flujo de OAuth 2.0.
  • Dos botones que permiten al usuario cerrar sesión en la aplicación o revocar el acceso previamente otorgado a la aplicación. Si cierra sesión en una aplicación, no ha revocado el acceso otorgado a la aplicación. Deberá iniciar sesión nuevamente antes de que la aplicación pueda realizar otras solicitudes autorizadas en su nombre, pero no tendrá que otorgar acceso nuevamente la próxima vez que use la aplicación. Sin embargo, si revoca el acceso, debe volver a otorgarlo.

También puede revocar el acceso a la aplicación a través de la página Permisos de su cuenta de Google. La aplicación figura como Demostración de OAuth 2.0 para Google API Docs .

<script>
  var GoogleAuth;
  var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
  function handleClientLoad() {
    // Load the API's client and auth2 modules.
    // Call the initClient function after the modules load.
    gapi.load('client:auth2', initClient);
  }

  function initClient() {
    // In practice, your app can retrieve one or more discovery documents.
    var discoveryUrl = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';

    // Initialize the gapi.client object, which app uses to make API requests.
    // Get API key and client ID from API Console.
    // 'scope' field specifies space-delimited list of access scopes.
    gapi.client.init({
        'apiKey': 'YOUR_API_KEY',
        'clientId': 'YOUR_CLIENT_ID',
        'discoveryDocs': [discoveryUrl],
        'scope': SCOPE
    }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);

      // Handle initial sign-in state. (Determine if user is already signed in.)
      var user = GoogleAuth.currentUser.get();
      setSigninStatus();

      // Call handleAuthClick function when user clicks on
      //      "Sign In/Authorize" button.
      $('#sign-in-or-out-button').click(function() {
        handleAuthClick();
      });
      $('#revoke-access-button').click(function() {
        revokeAccess();
      });
    });
  }

  function handleAuthClick() {
    if (GoogleAuth.isSignedIn.get()) {
      // User is authorized and has clicked "Sign out" button.
      GoogleAuth.signOut();
    } else {
      // User is not signed in. Start Google auth flow.
      GoogleAuth.signIn();
    }
  }

  function revokeAccess() {
    GoogleAuth.disconnect();
  }

  function setSigninStatus() {
    var user = GoogleAuth.currentUser.get();
    var isAuthorized = user.hasGrantedScopes(SCOPE);
    if (isAuthorized) {
      $('#sign-in-or-out-button').html('Sign out');
      $('#revoke-access-button').css('display', 'inline-block');
      $('#auth-status').html('You are currently signed in and have granted ' +
          'access to this app.');
    } else {
      $('#sign-in-or-out-button').html('Sign In/Authorize');
      $('#revoke-access-button').css('display', 'none');
      $('#auth-status').html('You have not authorized this app or you are ' +
          'signed out.');
    }
  }

  function updateSigninStatus() {
    setSigninStatus();
  }
</script>

<button id="sign-in-or-out-button"
        style="margin-left: 25px">Sign In/Authorize</button>
<button id="revoke-access-button"
        style="display: none; margin-left: 25px">Revoke access</button>

<div id="auth-status" style="display: inline; padding-left: 25px"></div><hr>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script async defer src="https://apis.google.com/js/api.js"
        onload="this.onload=function(){};handleClientLoad()"
        onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>

Extremos de OAuth 2.0

Este ejemplo de código demuestra cómo completar el flujo de OAuth 2.0 en JavaScript sin utilizar la biblioteca cliente de las API de Google para JavaScript. El código es para una página HTML que muestra un botón para probar una solicitud de API. Si hace clic en el botón, el código verifica si la página ha almacenado un token de acceso a la API en el almacenamiento local de su navegador. Si es así, ejecuta la solicitud de API. De lo contrario, inicia el flujo de OAuth 2.0.

Para el flujo de OAuth 2.0, la página sigue estos pasos:

  1. Dirige al usuario al servidor OAuth 2.0 de Google, que solicita acceso al alcance https://www.googleapis.com/auth/drive.metadata.readonly .
  2. Después de otorgar (o denegar) el acceso a uno o más ámbitos solicitados, el usuario es redirigido a la página original, que analiza el token de acceso de la cadena del identificador del fragmento.
  3. La página utiliza el token de acceso para realizar la solicitud de API de muestra.

    La solicitud de la API llama al método about.get la API de about.get para recuperar información sobre la cuenta de Google Drive del usuario autorizado.

  4. Si la solicitud se ejecuta correctamente, la respuesta de la API se registra en la consola de depuración del navegador.

Puede revocar el acceso a la aplicación a través de la página Permisos de su cuenta de Google. La aplicación aparecerá como Demostración de OAuth 2.0 para Google API Docs .

Para ejecutar este código localmente, debe establecer valores para las variables YOUR_CLIENT_ID y YOUR_REDIRECT_URI que correspondan a sus credenciales de autorización . La variable YOUR_REDIRECT_URI debe establecerse en la misma URL donde se YOUR_REDIRECT_URI la página. El valor debe coincidir exactamente con uno de los URI de redireccionamiento autorizados para el cliente OAuth 2.0, que configuró en API Console Credentials page. Si este valor no coincide con un URI autorizado, obtendrá un error redirect_uri_mismatch . Su proyecto también debe haber habilitado la API adecuada para esta solicitud.

<html><head></head><body>
<script>
  var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE';
  var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE';
  var fragmentString = location.hash.substring(1);

  // Parse query string to see if page request is coming from OAuth 2.0 server.
  var params = {};
  var regex = /([^&=]+)=([^&]*)/g, m;
  while (m = regex.exec(fragmentString)) {
    params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }
  if (Object.keys(params).length > 0) {
    localStorage.setItem('oauth2-test-params', JSON.stringify(params) );
    if (params['state'] && params['state'] == 'try_sample_request') {
      trySampleRequest();
    }
  }

  // If there's an access token, try an API request.
  // Otherwise, start OAuth 2.0 flow.
  function trySampleRequest() {
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    if (params && params['access_token']) {
      var xhr = new XMLHttpRequest();
      xhr.open('GET',
          'https://www.googleapis.com/drive/v3/about?fields=user&' +
          'access_token=' + params['access_token']);
      xhr.onreadystatechange = function (e) {
        if (xhr.readyState === 4 && xhr.status === 200) {
          console.log(xhr.response);
        } else if (xhr.readyState === 4 && xhr.status === 401) {
          // Token invalid, so prompt for user permission.
          oauth2SignIn();
        }
      };
      xhr.send(null);
    } else {
      oauth2SignIn();
    }
  }

  /*
   * Create form to request access token from Google's OAuth 2.0 server.
   */
  function oauth2SignIn() {
    // Google's OAuth 2.0 endpoint for requesting an access token
    var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

    // Create element to open OAuth 2.0 endpoint in new window.
    var form = document.createElement('form');
    form.setAttribute('method', 'GET'); // Send as a GET request.
    form.setAttribute('action', oauth2Endpoint);

    // Parameters to pass to OAuth 2.0 endpoint.
    var params = {'client_id': YOUR_CLIENT_ID,
                  'redirect_uri': YOUR_REDIRECT_URI,
                  'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                  'state': 'try_sample_request',
                  'include_granted_scopes': 'true',
                  'response_type': 'token'};

    // Add form parameters as hidden input values.
    for (var p in params) {
      var input = document.createElement('input');
      input.setAttribute('type', 'hidden');
      input.setAttribute('name', p);
      input.setAttribute('value', params[p]);
      form.appendChild(input);
    }

    // Add form to page and submit it to open the OAuth 2.0 endpoint.
    document.body.appendChild(form);
    form.submit();
  }
</script>

<button onclick="trySampleRequest();">Try sample request</button>
</body></html>

Reglas de validación de origen de JavaScript

Google aplica las siguientes reglas de validación a los orígenes de JavaScript para ayudar a los desarrolladores a mantener seguras sus aplicaciones. Sus orígenes de JavaScript deben cumplir con estas reglas. Consulte la sección 3 de RFC 3986 para obtener la definición de dominio, host y esquema, 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.
  • 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 alcances. 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 la 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, quizás 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 de la primera solicitud para guardar una mezcla.

    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 ámbitos de esa autorización en nombre del usuario asociado se revoca simultáneamente.

    Los ejemplos de código a continuación muestran cómo agregar ámbitos a un token de acceso existente. Este enfoque permite que su aplicación evite tener que administrar múltiples tokens de acceso.

    Biblioteca cliente JS

    Para agregar ámbitos a un token de acceso existente, llame al GoogleUser.grant(options) . El objeto de options identifica los ámbitos adicionales a los que desea otorgar acceso.

    // Space-separated list of additional scope(s) you are requesting access to.
    // This code adds read-only access to the user's calendars via the Calendar API.
    var NEW_SCOPES = 'https://www.googleapis.com/auth/calendar.readonly';
    
    // Retrieve the GoogleUser object for the current user.
    var GoogleUser = GoogleAuth.currentUser.get();
    GoogleUser.grant({'scope': NEW_SCOPES});

    Extremos de OAuth 2.0

    Para agregar alcances a un token de acceso existente, incluya el parámetro include_granted_scopes en su solicitud al servidor OAuth 2.0 de Google .

    El siguiente fragmento de código demuestra cómo hacerlo. El fragmento asume que ha almacenado los ámbitos para los que su token de acceso es válido en el almacenamiento local del navegador. (El código de ejemplo completo almacena una lista de ámbitos para los que el token de acceso es válido estableciendo la oauth2-test-params.scope en el almacenamiento local del navegador).

    El fragmento compara los ámbitos para los que el token de acceso es válido con el ámbito que desea usar para una consulta en particular. Si el token de acceso no cubre ese alcance, se inicia el flujo de OAuth 2.0. Aquí, la función oauth2SignIn es la misma que se proporcionó en el paso 2 (y que se proporciona más adelante en el ejemplo completo ).

    var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    
    var current_scope_granted = false;
    if (params.hasOwnProperty('scope')) {
      var scopes = params['scope'].split(' ');
      for (var s = 0; s < scopes.length; s++) {
        if (SCOPE == scopes[s]) {
          current_scope_granted = true;
        }
      }
    }
    
    if (!current_scope_granted) {
      oauth2SignIn(); // This function is defined elsewhere in this document.
    } else {
      // Since you already have access, you can proceed with the API request.
    }

    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.

    Biblioteca cliente JS

    Para revocar un token mediante programación, llame a GoogleAuth.disconnect() :

    GoogleAuth.disconnect();

    Extremos de OAuth 2.0

    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.

    El siguiente fragmento de JavaScript muestra cómo revocar un token en JavaScript sin utilizar la biblioteca cliente de las API de Google para JavaScript. Dado que el extremo OAuth 2.0 de Google para revocar tokens no admite el uso compartido de recursos de origen cruzado (CORS), el código crea un formulario y envía el formulario al extremo en lugar de utilizar el método XMLHttpRequest() para publicar la solicitud.

    function revokeAccess(accessToken) {
      // Google's OAuth 2.0 endpoint for revoking access tokens.
      var revokeTokenEndpoint = 'https://oauth2.googleapis.com/revoke';
    
      // Create <form> element to use to POST data to the OAuth 2.0 endpoint.
      var form = document.createElement('form');
      form.setAttribute('method', 'post');
      form.setAttribute('action', revokeTokenEndpoint);
    
      // Add access token to the form so it is set as value of 'token' parameter.
      // This corresponds to the sample curl request, where the URL is:
      //      https://oauth2.googleapis.com/revoke?token={token}
      var tokenField = document.createElement('input');
      tokenField.setAttribute('type', 'hidden');
      tokenField.setAttribute('name', 'token');
      tokenField.setAttribute('value', accessToken);
      form.appendChild(tokenField);
    
      // Add form to page and submit it to actually revoke the token.
      document.body.appendChild(form);
      form.submit();
    }