Cómo manejar permisos detallados

Descripción general

Con los permisos detallados, los consumidores obtienen un control más preciso sobre los datos de la cuenta que eligen compartir con cada app. Esto beneficia tanto a los usuarios como a los desarrolladores, ya que proporciona mayor control, transparencia y seguridad. Esta guía te ayudará a comprender los cambios y los pasos necesarios para actualizar correctamente tus aplicaciones para que controlen los permisos detallados.

¿Qué son los permisos detallados?

Imagina que desarrollas una app de productividad que solicita permisos de correo electrónico y de calendario. Es posible que los usuarios quieran usar tu aplicación solo para Calendario de Google, pero no para Gmail. Con los permisos detallados de OAuth los usuarios pueden elegir otorgar solo el permiso de Calendario de Google, pero no el de Gmail. Al permitir que los usuarios otorguen acceso a datos específicos, se minimiza la exposición de datos, se refuerza la confianza y se les otorga a los usuarios un control que prioriza la privacidad sobre su vida digital. Es importante diseñar tu aplicación para controlar estas situaciones.

Cuando se solicita más de un permiso que no es de acceso

Permisos de acceso y que no son de acceso

En el caso de las aplicaciones que solicitan permisos de acceso y que no son de acceso, los usuarios primero ven la página de consentimiento para permisos de acceso (email, profile, y openid). Después de que los usuarios dan su consentimiento para compartir su información de identidad básica (nombre, dirección de correo electrónico y foto de perfil), verán una pantalla de consentimiento de permisos detallados para los permisos que no son de acceso. En este caso, la aplicación debe verificar qué permisos otorgan los usuarios y no puede suponer que otorgan todos los permisos solicitados. En el siguiente ejemplo, la aplicación web solicita los tres permisos de acceso y un permiso de Google Drive que no es de acceso. Después de que los usuarios den su consentimiento para los permisos de acceso, verán la pantalla de consentimiento de permisos detallados para el permiso de Google Drive:

Alcances de acceso y sin acceso

Más de un permiso que no es de acceso

Se mostrará una pantalla de consentimiento de permisos detallados a los usuarios cuando las aplicaciones soliciten más de un permiso que no sea de acceso. Los usuarios pueden seleccionar los permisos que quieren aprobar para compartir con la aplicación. El siguiente es un ejemplo de pantalla de consentimiento de permisos detallados que solicita acceso a los mensajes de Gmail y a los datos de Calendario de Google del usuario:

Más de un alcance que no es de acceso

En el caso de las aplicaciones que solicitan solo permisos de acceso (email, profile y openid), no se aplica la pantalla de consentimiento de permisos detallados. Los usuarios aprueban o rechazan toda la solicitud de acceso. En otras palabras, si las aplicaciones solo solicitan permisos de acceso (uno, dos o los tres), no se aplica la pantalla de consentimiento de permisos detallados.

En el caso de las aplicaciones que solicitan solo un permiso que no es de acceso, no se aplica la pantalla de consentimiento de permisos detallados. En otras palabras, los usuarios aprueban o rechazan toda la solicitud, y no hay ninguna casilla de verificación en la pantalla de consentimiento. En la siguiente tabla , se resume cuándo se muestra la pantalla de consentimiento de permisos detallados.

Cantidad de permisos de acceso Cantidad de permisos que no son de acceso Pantalla de consentimiento de permisos detallados
1-3 0 No aplicable
1-3 1+ Servicios
0 1 No aplicable
0 2+ Servicios

Determina si tus aplicaciones se ven afectadas

Realiza una revisión exhaustiva de todas las secciones de tu aplicación en las que se utilizan los extremos de autorización de Google OAuth 2.0 para las solicitudes de permisos. Presta atención a las que solicitan varios permisos, ya que activan las pantallas de consentimiento de permisos detallados que se muestran a los usuarios. En esos casos, asegúrate de que tu código pueda controlar la situación en la que los usuarios solo autorizan algunos de los permisos.

Cómo determinar si tu aplicación usa varios permisos

Inspecciona el código de tu app o lallamada de red saliente para determinar si lassolicitudes de autorización de Google OAuth 2.0 que realiza tu app harán que se muestre la pantalla de consentimiento de permisos detallados.

Inspecciona el código de tu aplicación

Revisa las secciones del código de tu aplicación en las que realizas llamadas a los extremos de autorización de Google OAuth para solicitar permiso a los usuarios. Si usas una de las bibliotecas cliente de las APIs de Google, a menudo puedes encontrar qué permisos solicita tu aplicación en los pasos de inicialización del cliente. En la siguiente sección, se muestran algunos ejemplos. Debes consultar la documentación de los SDKs que usa tu aplicación para controlar Google OAuth 2.0 y determinar si tu aplicación se ve afectada, usando como referencia la guía que se muestra en los siguientes ejemplos.

Google Identity Services

El siguiente fragmento de código de la biblioteca de JavaScript de Google Identity Services inicializa TokenClient con varios permisos que no son de acceso. Se mostrará la pantalla de consentimiento de permisos detallados cuando la app web solicite autorización a los usuarios.

const client = google.accounts.oauth2.initTokenClient({
  client_id: 'YOUR_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly \
  https://www.googleapis.com/auth/contacts.readonly',
  callback: (response) => {
    ...
  },
});

Python

En el siguiente fragmento de código, se usa el google-auth-oauthlib.flow módulo para construir la solicitud de autorización. El parámetro scope incluye dos permisos que no son de acceso. Se mostrará la pantalla de consentimiento de permisos detallados cuando la aplicación web solicite autorización a los usuarios.

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/calendar.readonly',
                    'https://www.googleapis.com/auth/contacts.readonly'])

Node.js

El siguiente fragmento de código crea un objeto google.auth.OAuth2, que define los parámetros de la solicitud de autorización cuyo parámetro scope incluye dos permisos que no son de acceso. Se mostrará la pantalla de consentimiento de permisos detallados cuando la app web solicite autorización a los usuarios.

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

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

// Access scopes for read-only Calendar and Contacts.
const scopes = [
  'https://www.googleapis.com/auth/calendar.readonly',
  'https://www.googleapis.com/auth/contacts.readonly']
];

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

Inspecciona la llamada de red saliente

El método para inspeccionar las llamadas de red variará según el tipo de cliente de tu aplicación.

Mientras inspeccionas las llamadas de red, busca las solicitudes enviadas a los extremos de autorización de Google OAuth y examina el scope parámetro.

Estos valores hacen que se muestre la pantalla de consentimiento de permisos detallados.

  • El parámetro scope contiene permisos de acceso y permisos que no son de acceso.

    La siguiente solicitud de muestra contiene los tres permisos de acceso y un permiso que no es de acceso para ver los metadatos de los archivos de Google Drive del usuario:

    https://accounts.google.com/o/oauth2/v2/auth?
    access_type=offline&
    scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile%20openid%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly&
    include_granted_scopes=true&
    response_type=code&
    redirect_uri=YOUR_REDIRECT_URL&
    client_id=YOUR_CLIENT_ID
  • El parámetro scope contiene más de un permiso que no es de acceso.

    La siguiente solicitud de muestra contiene dos permisos que no son de acceso para ver los metadatos de Google Drive del usuario y administrar archivos específicos de Google Drive:

  • https://accounts.google.com/o/oauth2/v2/auth?
    access_type=offline&
    scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.file&
    include_granted_scopes=true&
    response_type=code&
    redirect_uri=YOUR_REDIRECT_URL&
    client_id=YOUR_CLIENT_ID

Prácticas recomendadas para controlar los permisos detallados

Si determinas que se debe actualizar tu aplicación para controlar los permisos detallados, debes realizar las actualizaciones necesarias en tu código para controlar correctamente el consentimiento de varios permisos. Todas las aplicaciones deben cumplir con las siguientes prácticas recomendadas:

  1. Revisa la Política de Datos del Usuario de los Servicios de las APIs de Google y asegúrate de cumplir con ella.
  2. Solicita permisos específicos que sean necesarios para una tarea. Debes cumplir con la política de Google OAuth 2.0 que solo solicita los permisos que necesitas. Debes evitar solicitar varios permisos durante el acceso, a menos que sea esencial para la funcionalidad principal de tu app. Agrupar varios permisos, en especial para los usuarios nuevos que no están familiarizados con las funciones de tu aplicación, puede dificultarles la comprensión de la necesidad de estos permisos. Esto puede generar alarmas y disuadir a los usuarios de seguir interactuando con tu aplicación.
  3. Proporciona una justificación a los usuarios antes de solicitar la solicitud de autorización. Explica claramente por qué tu aplicación necesita el permiso solicitado, qué harás con los datos del usuario y cómo se beneficiará el usuario si aprueba la solicitud. Nuestra investigación indica que estas explicaciones aumentan la confianza y la participación de los usuarios.
  4. Usa la autorización incremental cada vez que tu aplicación solicite permisos para evitar tener que administrar varios tokens de acceso.
  5. Verifica qué permisos otorgaron los usuarios. Cuando solicitan varios permisos a la vez, es posible que los usuarios no otorguen todos los permisos que solicita tu app. Tu app siempre debe verificar qué permisos otorgó el usuario y controlar cualquier rechazo de permisos inhabilitando las funciones pertinentes. Sigue las políticas de Google OAuth 2.0 sobre el control del consentimiento para varios permisos y solo vuelve a solicitar el consentimiento del usuario una vez que haya indicado claramente su intención de usar la función específica que requiere el permiso.

Actualiza tu aplicación para controlar los permisos detallados

Aplicaciones para Android

Debes consultar la documentación de los SDKs que usas para interactuar con Google OAuth 2.0 y actualizar tu aplicación para controlar los permisos detallados según las prácticas recomendadas.

Si usas auth.api.signin SDK de Play Services para interactuar con Google OAuth 2.0, puedes usar requestPermissions función para solicitar el conjunto más pequeño de permisos necesarios, y la hasPermissions función para verificar qué permisos otorgó el usuario cuando solicitó permisos detallados.

Aplicaciones de extensión de Chrome

Debes usar Chrome Identity API para trabajar con Google OAuth 2.0 según las prácticas recomendadas.

En el siguiente ejemplo, se muestra cómo controlar correctamente los permisos detallados.

manifest.json

El archivo de manifiesto de ejemplo declara dos permisos que no son de acceso para la aplicación de extensión de Chrome.

{
  "name": "Example Chrome extension application",
  ...
  "permissions": [
      "identity"
    ],
  "oauth2" : {
      "client_id": "YOUR_CLIENT_ID",
      "scopes":["https://www.googleapis.com/auth/calendar.readonly",
                "https://www.googleapis.com/auth/contacts.readonly"]
  }
}

Enfoque incorrecto

Todo o nada

Los usuarios hacen clic en el botón para iniciar el proceso de autorización. El fragmento de código supone que los usuarios ven una pantalla de consentimiento de "todo o nada" para los dos permisos especificados en el archivo manifest.json. No verifica qué permisos otorgaron los usuarios.

oauth.js

...
document.querySelector('button').addEventListener('click', function () {
  chrome.identity.getAuthToken({ interactive: true },
      function (token) {
          if (token === undefined) {
            // User didn't authorize both scopes.
            // Updating the UX and application accordingly
            ...
          } else {
            // User authorized both or one of the scopes.
            // It neglects to check which scopes users granted and assumes users granted all scopes.

            // Calling the APIs, etc.
            ...
          }
      });
});

Enfoque correcto

Permisos más pequeños

Selecciona el conjunto más pequeño de permisos necesarios

La aplicación solo debe solicitar el conjunto más pequeño de permisos necesarios. Se recomienda que tu aplicación solicite un permiso a la vez cuando sea necesario para completar una tarea.

En este ejemplo, se supone que ambos permisos declarados en el manifest.json archivo son el conjunto más pequeño de permisos necesarios. El archivo oauth.js usa la API de Chrome Identity para iniciar el proceso de autorización con Google. Debes habilitar para habilitar los permisos detallados, de modo que los usuarios tengan un mayor control para otorgar permisos a tu aplicación. Tu aplicación debe controlar correctamente la respuesta de los usuarios verificando qué permisos autorizan.

oauth.js

...
document.querySelector('button').addEventListener('click', function () {
  chrome.identity.getAuthToken({ interactive: true, enableGranularPermissions: true },
      function (token, grantedScopes) {
          if (token === undefined) {
            // User didn't authorize any scope.
            // Updating the UX and application accordingly
            ...
          } else {
            // User authorized the request. Now, check which scopes were granted.
            if (grantedScopes.includes('https://www.googleapis.com/auth/calendar.readonly'))
            {
              // User authorized Calendar read permission.
              // Calling the APIs, etc.
              ...
            }
            else
            {
              // User didn't authorize Calendar read permission.
              // Update UX and application accordingly
              ...
            }

            if (grantedScopes.includes('https://www.googleapis.com/auth/contacts.readonly'))
            {
              // User authorized Contacts read permission.
              // Calling the APIs, etc.
              ...
            }
            else
            {
              // User didn't authorize Contacts read permission.
              // Update UX and application accordingly
              ...
            }
          }
      });
});

Aplicaciones para iOS, iPadOS y macOS

Debes consultar la documentación de los SDKs que usas para interactuar con Google OAuth 2.0 y actualizar tu aplicación para controlar los permisos detallados según las prácticas recomendadas.

Si usas la biblioteca Acceso con Google para iOS y macOS para interactuar con Google OAuth 2.0, debes revisar la documentación sobre el control de permisos detallados.

Aplicaciones web

Debes consultar la documentación de los SDKs que usas para interactuar con Google OAuth 2.0 y actualizar tu aplicación para controlar los permisos detallados según las prácticas recomendadas.

Acceso del servidor (sin conexión)

El modo de acceso del servidor (sin conexión) requiere que hagas lo siguiente:
  • Configura un servidor y define un extremo de acceso público para recibir el código de autorización.
  • Configura el URI de redireccionamiento de tu extremo público en la página Clientes de la consola de Google Cloud.

En el siguiente fragmento de código, se muestra un ejemplo de NodeJS que solicita dos permisos que no son de acceso. Los usuarios verán la pantalla de consentimiento de permisos detallados.

Enfoque incorrecto

Todo o nada

Se redirecciona a los usuarios a la URL de autorización. El fragmento de código supone que los usuarios ven una pantalla de consentimiento de "todo o nada" para los dos permisos especificados en el scopes array. No verifica qué permisos otorgaron los usuarios.

main.js

...
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for two non-Sign-In scopes - Google Calendar and Contacts
const scopes = [
  'https://www.googleapis.com/auth/contacts.readonly',
  'https://www.googleapis.com/auth/calendar.readonly'
];

// Generate a url that asks permissions for the Google Calendar and Contacts scopes
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  // Pass in the scopes array defined above
  scope: scopes,
  // Enable incremental authorization. Recommended as best practices.
  include_granted_scopes: true
});

async function main() {
  const server = http.createServer(async function (req, res) {
    // Example on redirecting user to Google OAuth 2.0 server.
    if (req.url == '/') {
      res.writeHead(301, { "Location": authorizationUrl });
    }
    // Receive the callback from Google OAuth 2.0 server.
    if (req.url.startsWith('/oauth2callback')) {
      // Handle the Google OAuth 2.0 server response
      let q = url.parse(req.url, true).query;

      if (q.error) {
        // User didn't authorize both scopes.
        // Updating the UX and application accordingly
        ...
      } else {
        // User authorized both or one of the scopes.
        // It neglects to check which scopes users granted and assumes users granted all scopes.

        // Get access and refresh tokens (if access_type is offline)
        let { tokens } = await oauth2Client.getToken(q.code);
        // Calling the APIs, etc.
        ...
      }
    }
    res.end();
  }).listen(80);
}
Enfoque correcto

Permiso más pequeño

Selecciona el conjunto más pequeño de permisos necesarios

La aplicación solo debe solicitar el conjunto más pequeño de permisos necesarios. Se recomienda que tu aplicación solicite un permiso a la vez cuando sea necesario para completar una tarea. Cada vez que tu aplicación solicite permisos, debe usar la autorización incremental para evitar tener que administrar varios tokens de acceso.

Si tu aplicación debe solicitar varios permisos que no son de acceso, siempre debes usar la autorización incremental cuando la solicites y verificar qué permisos otorgaron los usuarios.

En este ejemplo, se supone que ambos permisos indicados son necesarios para que la app funcione correctamente. Debes habilitar para habilitar los permisos detallados, de modo que los usuarios tengan un mayor control para otorgar permisos a tu aplicación. Tu aplicación debe controlar correctamente la respuesta de los usuarios verificando qué permisos autorizaron.

main.js

...
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for two non-Sign-In scopes - Google Calendar and Contacts
const scopes = [
  'https://www.googleapis.com/auth/contacts.readonly',
  'https://www.googleapis.com/auth/calendar.readonly'
];

// Generate a url that asks permissions for the Google Calendar and Contacts scopes
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  // Pass in the scopes array defined above
  scope: scopes,
  // Enable incremental authorization. Recommended as best practices.
  include_granted_scopes: true,
  // Set to true to enable more granular permissions for Google OAuth 2.0 client IDs created before 2019.
  // No effect for newer Google OAuth 2.0 client IDs, since more granular permissions is always enabled for them.
  enable_granular_consent: true
});

async function main() {
  const server = http.createServer(async function (req, res) {
    // Redirect users to Google OAuth 2.0 server.
    if (req.url == '/') {
      res.writeHead(301, { "Location": authorizationUrl });
    }
    // Receive the callback from Google OAuth 2.0 server.
    if (req.url.startsWith('/oauth2callback')) {
      // Handle the Google OAuth 2.0 server response
      let q = url.parse(req.url, true).query;

      if (q.error) {
        // User didn't authorize both scopes.
        // Updating the UX and application accordingly
        ...
      } else {
        // Get access and refresh tokens (if access_type is offline)
        let { tokens } = await oauth2Client.getToken(q.code);
        oauth2Client.setCredentials(tokens);

        // User authorized the request. Now, check which scopes were granted.
        if (tokens.scope.includes('https://www.googleapis.com/auth/calendar.readonly'))
        {
          // User authorized Calendar read permission.
          // Calling the APIs, etc.
          ...
        }
        else
        {
          // User didn't authorize Calendar read permission.
          // Calling the APIs, etc.
          ...
        }

        // Check which scopes user granted the permission to application
        if (tokens.scope.includes('https://www.googleapis.com/auth/contacts.readonly'))
        {
          // User authorized Contacts read permission.
          // Calling the APIs, etc.
          ...
        }
        else
        {
          // User didn't authorize Contacts read permission.
          // Update UX and application accordingly
          ...
        }
      }
    }
    res.end();
  }).listen(80);
}

Revisa la guía de apps web del servidor sobre cómo acceder a las APIs de Google desde aplicaciones basadas en servidores.

Acceso solo del cliente

  • En el caso de las aplicaciones que usan Google Identity Services la biblioteca de JavaScript para interactuar con Google OAuth 2.0, debes revisar esta documentación sobre el control de permisos detallados.
  • En el caso de las aplicaciones que realizan llamadas directamente con JavaScript a los extremos de autorización de Google OAuth 2.0 debes revisar esta documentación sobre el control de permisos detallados.

Prueba tu aplicación actualizada para controlar los permisos detallados

  1. Describe todos los casos en los que los usuarios pueden responder a las solicitudes de permisos y el comportamiento esperado de tu aplicación. Por ejemplo, si el usuario solo autoriza dos de los tres permisos solicitados, tu aplicación debe comportarse en consecuencia.
  2. Prueba tu aplicación con los permisos detallados habilitados. Existen dos maneras de habilitar los permisos detallados:
    1. Revisa las pantallas de consentimiento de OAuth 2.0 de tu aplicación para ver si los permisos detallados ya están habilitados para tu aplicación. También puedes crear un nuevo ID de cliente de Google OAuth 2.0 para la Web, Android o iOS a través de la consola de Google Cloud para realizar pruebas, ya que los permisos detallados siempre están habilitados para ellos.
    2. Configura el parámetro enable_granular_consent en true cuando llames a los extremos de autorización de Google OAuth . Algunos SDKs tienen compatibilidad explícita con este parámetro. Para otros, consulta la documentación para ver cómo puedes agregar este parámetro y su valor de forma manual. Si tu implementación no admite la adición del parámetro, puedes crear un nuevo ID de cliente de Google OAuth 2.0 para la Web, Android o iOS a través de la consola de Google Cloud solo para realizar pruebas, como se indica en el punto anterior.
  3. Cuando pruebes tu aplicación actualizada, usa una Cuenta de Google personal (@gmail.com) en lugar de una cuenta de Workspace. Esto se debe a que las apps de Workspace Enterprise con delegación de autoridad en todo el dominio o marcadas como Confiables no se ven afectadas por los cambios en los permisos detallados en este momento. Por lo tanto, es posible que las pruebas con una cuenta de Workspace de tu organización no muestren la nueva pantalla de consentimiento detallado como se espera.