El sistema de OAuth 2.0 de Google admite interacciones de servidor a servidor, como las que se producen entre una aplicación web y un servicio de Google. Para este caso, necesitas una cuenta de servicio, que es una cuenta que pertenece a tu aplicación y no a un usuario final individual. Tu aplicación llama a las APIs de Google en nombre de la cuenta de servicio, por lo que los usuarios no están involucrados de manera directa. A veces, este caso se denomina "OAuth de dos segmentos" o "2LO". (El término relacionado "OAuth de tres segmentos" hace referencia a situaciones en las que tu aplicación llama a las APIs de Google en nombre de los usuarios finales y en las que, a veces, se requiere el consentimiento del usuario).
Por lo general, una aplicación usa una cuenta de servicio cuando usa las APIs de Google para trabajar con sus propios datos en lugar de los datos de un usuario. Por ejemplo, una aplicación que usa Google Cloud Datastore para la persistencia de datos usaría una cuenta de servicio para autenticar sus llamadas a la API de Google Cloud Datastore.
Los administradores de dominios de Google Workspace también pueden otorgar autoridad en todo el dominio a las cuentas de servicio para acceder a los datos del usuario en nombre de los usuarios del dominio.
En este documento, se describe cómo una aplicación puede completar el flujo de OAuth 2.0 de servidor a servidor usando una biblioteca cliente de las APIs de Google (recomendado) o HTTP.
Descripción general
Para admitir interacciones de servidor a servidor, primero crea una cuenta de servicio para tu proyecto en API Console. Si deseas acceder a los datos de los usuarios de tu cuenta de Google Workspace, delega el acceso a todo el dominio a la cuenta de servicio.
Luego, tu aplicación se prepara para realizar llamadas autorizadas a la API con las credenciales de la cuenta de servicio para solicitar un token de acceso del servidor de autorización de OAuth 2.0.
Por último, tu aplicación puede usar el token de acceso para llamar a las APIs de Google.
Crea una cuenta de servicio
Las credenciales de una cuenta de servicio incluyen una dirección de correo electrónico generada que es única y, al menos, un par de claves públicas/privadas. Si la delegación en todo el dominio está habilitada, el ID de cliente también forma parte de las credenciales de la cuenta de servicio.
Si tu aplicación se ejecuta en Google App Engine, se configura automáticamente una cuenta de servicio cuando creas tu proyecto.
Si tu aplicación se ejecuta en Google Compute Engine, también se configura una cuenta de servicio automáticamente cuando creas tu proyecto, pero debes especificar los alcances a los que tu aplicación necesita acceder cuando creas una instancia de Google Compute Engine. Para obtener más información, consulta Cómo preparar una instancia para usar cuentas de servicio.
Si tu aplicación no se ejecuta en Google App Engine ni en Google Compute Engine, debes obtener estas credenciales en Google API Console. Para generar credenciales de cuenta de servicio o ver las credenciales públicas que ya generaste, haz lo siguiente:
Primero, crea una cuenta de servicio:
- Abra el Service accounts page.
- If prompted, select a project, or create a new one.
- Haz clic en Crear cuenta de servicio .
- En Detalles de la cuenta de servicio , escriba un nombre, ID y descripción para la cuenta de servicio, luego haga clic en Crear y continuar .
- Opcional: en Otorgar a esta cuenta de servicio acceso al proyecto , seleccione las funciones de IAM para otorgar a la cuenta de servicio.
- Haga clic en Continuar .
- Opcional: en Otorgar acceso a los usuarios a esta cuenta de servicio , agregue los usuarios o grupos que pueden usar y administrar la cuenta de servicio.
- Haga clic en Listo .
A continuación, cree una clave de cuenta de servicio:
- Haga clic en la dirección de correo electrónico de la cuenta de servicio que creó.
- Haga clic en la pestaña Claves .
- En la lista desplegable Agregar clave , seleccione Crear nueva clave .
- Haz clic en Crear .
Su nuevo par de claves pública/privada se genera y descarga en su máquina; sirve como la única copia de la clave privada. Usted es responsable de almacenarlo de forma segura. Si pierde este par de claves, deberá generar uno nuevo.
Puedes volver a API Console en cualquier momento para ver la dirección de correo electrónico, las huellas digitales de la clave pública y otra información, o para generar pares de claves pública y privada adicionales. Para obtener más detalles sobre las credenciales de la cuenta de servicio en API Console, consulta Cuentas de servicio en el archivo de ayuda de API Console.
Toma nota de la dirección de correo electrónico de la cuenta de servicio y almacena el archivo de claves privadas de la cuenta de servicio en una ubicación a la que pueda acceder tu aplicación. Tu aplicación los necesita para realizar llamadas a la API autorizadas.
Delegar autoridad en todo el dominio a la cuenta de servicio
Con una cuenta de Google Workspace, un administrador de Workspace de la organización puede autorizar a una aplicación para que acceda a los datos de los usuarios de Workspace en nombre de los usuarios del dominio de Google Workspace. Por ejemplo, una aplicación que usa la API de Calendario de Google para agregar eventos a los calendarios de todos los usuarios en un dominio de Google Workspace usará una cuenta de servicio para acceder a la API de Calendario de Google en nombre de los usuarios. La autorización de una cuenta de servicio para acceder a los datos en nombre de los usuarios en un dominio se conoce como "delegación de la autoridad de todo el dominio" a una cuenta de servicio.
Para delegar autoridad en todo el dominio a una cuenta de servicio, un administrador avanzado del dominio de Google Workspace debe completar los siguientes pasos:
- En la Consola del administrador de tu dominio de Google Workspace, ve a Menú principal > Seguridad > Control de acceso y datos > Controles de API.
- En el panel Delegación de todo el dominio, selecciona Administrar la delegación de todo el dominio.
- Haz clic en Agregar nueva.
- En el campo ID de cliente, ingresa el ID de cliente de la cuenta de servicio. Puedes encontrar el ID de cliente de tu cuenta de servicio en Service accounts page.
- En el campo Permisos de OAuth (delimitados por comas), ingresa la lista de permisos a los que se debe otorgar acceso a tu aplicación. Por ejemplo, si tu aplicación necesita acceso completo a nivel del dominio a la API de Google Drive y a la API de Google Calendar, ingresa https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar.
- Haz clic en Autorizar.
Tu aplicación ahora tiene autoridad para realizar llamadas a la API como usuarios de tu dominio de Workspace (para "suplantar" a los usuarios). Cuando te prepares para realizar estas llamadas a la API delegadas, especificarás de forma explícita el usuario al que suplantarás.
Preparación para realizar una llamada a la API delegada
Java
Después de obtener la dirección de correo electrónico del cliente y la clave privada de API Console, usa la biblioteca de Google Auth para Java para crear un objeto GoogleCredentials
a partir de las credenciales de la cuenta de servicio y los alcances a los que necesita acceder tu aplicación. Por ejemplo:
import com.google.auth.oauth2.GoogleCredentials; import com.google.api.services.sqladmin.SQLAdminScopes; // ... GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("MyProject-1234.json")) .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN));
Si estás desarrollando una app en Google Cloud Platform, puedes usar las credenciales predeterminadas de la aplicación, lo que puede simplificar el proceso.
Delega autoridad en todo el dominio
Si delegaste el acceso a todo el dominio a la cuenta de servicio y deseas suplantar una cuenta de usuario, especifica la dirección de correo electrónico de la cuenta de usuario con el método createDelegated
del objeto GoogleCredentials
. Por ejemplo:
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("MyProject-1234.json")) .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN)) .createDelegated("workspace-user@example.com");
El código anterior usa el objeto GoogleCredentials
para llamar a su método createDelegated()
. El argumento del método createDelegated()
debe ser un usuario que pertenezca a tu cuenta de Workspace. El código que realiza la solicitud usará esta credencial para llamar a las APIs de Google con tu cuenta de servicio.
Python
Después de obtener la dirección de correo electrónico del cliente y la clave privada de API Console, usa la biblioteca cliente de las APIs de Google para Python para completar los siguientes pasos:
- Crea un objeto
Credentials
a partir de las credenciales de la cuenta de servicio y los alcances a los que tu aplicación necesita acceder. Por ejemplo:from google.oauth2 import service_account SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin'] SERVICE_ACCOUNT_FILE = '/path/to/service.json' credentials = service_account.Credentials.from_service_account_file( SERVICE_ACCOUNT_FILE, scopes=SCOPES)
Si desarrollas una app en Google Cloud Platform, puedes usar las credenciales predeterminadas de la aplicación en su lugar, lo que puede simplificar el proceso.
- Delega autoridad en todo el dominio
Si delegaste el acceso a todo el dominio en la cuenta de servicio y deseas suplantar una cuenta de usuario, usa el método
with_subject
de un objetoServiceAccountCredentials
existente. Por ejemplo:delegated_credentials = credentials.with_subject('user@example.org')
Usa el objeto Credentials para llamar a las APIs de Google en tu aplicación.
HTTP/REST
Después de obtener el ID de cliente y la clave privada de API Console, tu aplicación debe completar los siguientes pasos:
- Crea un token web JSON (JWT, pronunciado "jot") que incluya un encabezado, un conjunto de reclamaciones y una firma.
- Solicita un token de acceso al servidor de autorización de OAuth 2.0 de Google.
- Controla la respuesta JSON que devuelve el servidor de autorización.
En las siguientes secciones, se describe cómo completar estos pasos.
Si la respuesta incluye un token de acceso, puedes usarlo para llamar a una API de Google. (Si la respuesta no incluye un token de acceso, es posible que tu JWT y tu solicitud de token no estén bien formados, o que la cuenta de servicio no tenga permiso para acceder a los permisos solicitados).
Cuando el token de acceso vence, tu aplicación genera otro JWT, lo firma y solicita otro token de acceso.

En el resto de esta sección, se describen los detalles específicos para crear un JWT, firmarlo, formar la solicitud del token de acceso y controlar la respuesta.
Cómo crear un JWT
Un JWT se compone de tres partes: un encabezado, un conjunto de reclamos y una firma. El encabezado y el conjunto de reclamos son objetos JSON. Estos objetos JSON se serializan en bytes UTF-8 y, luego, se codifican con la codificación Base64url. Esta codificación proporciona resistencia a los cambios de codificación debido a operaciones de codificación repetidas. El encabezado, el conjunto de reclamos y la firma se concatenan con un carácter de punto (.
).
Un JWT se compone de la siguiente manera:
{Base64url encoded header}.{Base64url encoded claim set}.{Base64url encoded signature}
La cadena base para la firma es la siguiente:
{Base64url encoded header}.{Base64url encoded claim set}
Cómo formar el encabezado JWT
El encabezado consta de tres campos que indican el algoritmo de firma, el formato de la aserción y el [ID de clave de la clave de la cuenta de servicio](https://cloud.google.com/iam/docs/reference/rest/v1/projects.serviceAccounts.keys) que se usó para firmar el JWT. El algoritmo y el formato son obligatorios, y cada campo solo tiene un valor. A medida que se introduzcan algoritmos y formatos adicionales, este encabezado cambiará según corresponda. El ID de clave es opcional y, si se especifica un ID de clave incorrecto, GCP intentará usar todas las claves asociadas con la cuenta de servicio para verificar el token y lo rechazará si no se encuentra una clave válida. En el futuro, Google se reserva el derecho de rechazar tokens con IDs de clave incorrectos.
Las cuentas de servicio se basan en el algoritmo RSA SHA-256 y el formato de token JWT. Como resultado, la representación JSON del encabezado es la siguiente:
{"alg":"RS256","typ":"JWT", "kid":"370ab79b4513eb9bad7c9bd16a95cb76b5b2a56a"}
La representación en Base64url es la siguiente:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsICJraWQiOiIzNzBhYjc5YjQ1MTNlYjliYWQ3YzliZDE2YTk1Y2I3NmI1YjJhNTZhIn0=
Cómo formar el conjunto de reclamaciones del JWT
El conjunto de reclamaciones del JWT contiene información sobre el JWT, incluidos los permisos que se solicitan (alcances), el destino del token, la entidad emisora, la hora en que se emitió el token y la vida útil del token. La mayoría de los campos son obligatorios. Al igual que el encabezado del JWT, el conjunto de reclamos del JWT es un objeto JSON y se usa en el cálculo de la firma.
Declaraciones obligatorias
A continuación, se muestran las reclamaciones obligatorias en el conjunto de reclamaciones del JWT. Pueden aparecer en cualquier orden en el conjunto de reclamos.
Nombre | Descripción |
---|---|
iss |
Es la dirección de correo electrónico de la cuenta de servicio. |
scope |
Es una lista de los permisos que solicita la aplicación, delimitada por espacios. |
aud |
Es un descriptor del destino previsto de la aserción. Cuando se realiza una solicitud de token de acceso, este valor siempre es https://oauth2.googleapis.com/token . |
exp |
Es la hora de vencimiento de la aserción, especificada como segundos desde las 00:00:00 UTC del 1 de enero de 1970. Este valor tiene un máximo de 1 hora después de la hora de emisión. |
iat |
Es la fecha y hora en que se emitió la aserción, especificada como segundos desde las 00:00:00 UTC del 1 de enero de 1970. |
A continuación, se muestra la representación JSON de los campos obligatorios en un conjunto de declaraciones de JWT:
{ "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com", "scope": "https://www.googleapis.com/auth/devstorage.read_only", "aud": "https://oauth2.googleapis.com/token", "exp": 1328554385, "iat": 1328550785 }
Reclamos adicionales
En algunos casos empresariales, una aplicación puede usar la delegación en todo el dominio para actuar en nombre de un usuario específico de una organización. Se debe otorgar permiso para realizar este tipo de suplantación antes de que una aplicación pueda suplantar a un usuario, y, por lo general, lo maneja un administrador avanzado. Para obtener más información, consulta Cómo controlar el acceso a la API con la delegación para todo el dominio.
Para obtener un token de acceso que le otorgue a una aplicación acceso delegado a un recurso, incluye la dirección de correo electrónico del usuario en el conjunto de reclamaciones del JWT como el valor del campo sub
.
Nombre | Descripción |
---|---|
sub |
Es la dirección de correo electrónico del usuario para el que la aplicación solicita acceso delegado. |
Si una aplicación no tiene permiso para suplantar la identidad de un usuario, la respuesta a una solicitud de token de acceso que incluya el campo sub
será un error.
A continuación, se muestra un ejemplo de un conjunto de reclamos de JWT que incluye el campo sub
:
{ "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com", "sub": "some.user@example.com", "scope": "https://www.googleapis.com/auth/prediction", "aud": "https://oauth2.googleapis.com/token", "exp": 1328554385, "iat": 1328550785 }
Codificación del conjunto de reclamaciones de JWT
Al igual que el encabezado del JWT, el conjunto de reclamos del JWT debe serializarse en UTF-8 y codificarse de forma segura para Base64url. A continuación, se muestra un ejemplo de una representación JSON de un conjunto de declaraciones de JWT:
{ "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com", "scope": "https://www.googleapis.com/auth/prediction", "aud": "https://oauth2.googleapis.com/token", "exp": 1328554385, "iat": 1328550785 }
Cómo calcular la firma
JSON Web Signature (JWS) es la especificación que guía la mecánica de generación de la firma para el JWT. La entrada para la firma es el array de bytes del siguiente contenido:
{Base64url encoded header}.{Base64url encoded claim set}
El algoritmo de firma en el encabezado del JWT se debe usar cuando se calcula la firma. El único algoritmo de firma compatible con el servidor de autorización de OAuth 2.0 de Google es RSA con el algoritmo de hash SHA-256. Esto se expresa como RS256
en el campo alg
del encabezado del JWT.
Firma la representación UTF-8 de la entrada con SHA256withRSA (también conocido como RSASSA-PKCS1-V1_5-SIGN con la función hash SHA-256) con la clave privada obtenida de Google API Console. El resultado será un array de bytes.
Luego, la firma debe codificarse en Base64url. El encabezado, el conjunto de reclamos y la firma se concatenan con un carácter de punto (.
). El resultado es el JWT. Debería ser lo siguiente (se agregaron saltos de línea para mayor claridad):
{Base64url encoded header}. {Base64url encoded claim set}. {Base64url encoded signature}
A continuación, se muestra un ejemplo de un JWT antes de la codificación en Base64url:
{"alg":"RS256","typ":"JWT"}. { "iss":"761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com", "scope":"https://www.googleapis.com/auth/prediction", "aud":"https://oauth2.googleapis.com/token", "exp":1328554385, "iat":1328550785 }. [signature bytes]
A continuación, se muestra un ejemplo de un JWT que se firmó y está listo para la transmisión:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL29hdXRoMi92NC90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ.UFUt59SUM2_AW4cRU8Y0BYVQsNTo4n7AFsNrqOpYiICDu37vVt-tw38UKzjmUKtcRsLLjrR3gFW3dNDMx_pL9DVjgVHDdYirtrCekUHOYoa1CMR66nxep5q5cBQ4y4u2kIgSvChCTc9pmLLNoIem-ruCecAJYgI9Ks7pTnW1gkOKs0x3YpiLpzplVHAkkHztaXiJdtpBcY1OXyo6jTQCa3Lk2Q3va1dPkh_d--GU2M5flgd8xNBPYw4vxyt0mP59XZlHMpztZt0soSgObf7G3GXArreF_6tpbFsS3z2t5zkEiHuWJXpzcYr5zWTRPDEHsejeBSG8EgpLDce2380ROQ
Cómo realizar la solicitud del token de acceso
Después de generar el JWT firmado, una aplicación puede usarlo para solicitar un token de acceso.
Esta solicitud de token de acceso es una solicitud POST
HTTPS, y el cuerpo está codificado como URL. La URL se muestra a continuación:
https://oauth2.googleapis.com/token
Se requieren los siguientes parámetros en la solicitud HTTPS POST
:
Nombre | Descripción |
---|---|
grant_type |
Usa la siguiente cadena, codificada en URL según sea necesario:
urn:ietf:params:oauth:grant-type:jwt-bearer |
assertion |
Es el JWT, incluida la firma. |
A continuación, se muestra un volcado sin procesar de la solicitud POST
HTTPS que se usa en una solicitud de token de acceso:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.ixOUGehweEVX_UKXv5BbbwVEdcz6AYS-6uQV6fGorGKrHf3LIJnyREw9evE-gs2bmMaQI5_UbabvI4k-mQE4kBqtmSpTzxYBL1TCd7Kv5nTZoUC1CmwmWCFqT9RE6D7XSgPUh_jF1qskLa2w0rxMSjwruNKbysgRNctZPln7cqQ
A continuación, se muestra la misma solicitud con curl
:
curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.RZVpzWygMLuL-n3GwjW1_yhQhrqDacyvaXkuf8HcJl8EtXYjGjMaW5oiM5cgAaIorrqgYlp4DPF_GuncFqg9uDZrx7pMmCZ_yHfxhSCXru3gbXrZvAIicNQZMFxrEEn4REVuq7DjkTMyCMGCY1dpMa8aWfTQFt3Eh7smLchaZsU ' https://oauth2.googleapis.com/token
Cómo controlar la respuesta
Si el JWT y la solicitud de token de acceso están bien formados y la cuenta de servicio tiene permiso para realizar la operación, la respuesta JSON del servidor de autorización incluye un token de acceso. A continuación, se muestra una respuesta de ejemplo:
{ "access_token": "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M", "scope": "https://www.googleapis.com/auth/prediction" "token_type": "Bearer", "expires_in": 3600 }
Los tokens de acceso se pueden reutilizar durante el período especificado por el valor de expires_in
.
Llama a las APIs de Google
Java
Usa el objeto GoogleCredentials
para llamar a las APIs de Google. Para ello, completa los siguientes pasos:
- Crea un objeto de servicio para la API a la que deseas llamar con el objeto
GoogleCredentials
. Por ejemplo:SQLAdmin sqladmin = new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credentials).build();
- Realiza solicitudes al servicio de la API con la interfaz proporcionada por el objeto de servicio.
Por ejemplo, para enumerar las instancias de bases de datos de Cloud SQL en el proyecto exciting-example-123, haz lo siguiente:
SQLAdmin.Instances.List instances = sqladmin.instances().list("exciting-example-123").execute();
Python
Completa los siguientes pasos para usar el objeto Credentials
autorizado y llamar a las APIs de Google:
- Compila un objeto de servicio para la API a la que deseas llamar. Para compilar un objeto de servicio, llama a la función
build
con el nombre y la versión de la API, y el objetoCredentials
autorizado. Por ejemplo, para llamar a la versión 1beta3 de la API de Cloud SQL Administration, haz lo siguiente:import googleapiclient.discovery sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', credentials=credentials)
- Realiza solicitudes al servicio de la API con la interfaz proporcionada por el objeto de servicio.
Por ejemplo, para enumerar las instancias de bases de datos de Cloud SQL en el proyecto exciting-example-123, haz lo siguiente:
response = sqladmin.instances().list(project='exciting-example-123').execute()
HTTP/REST
Después de que tu aplicación obtenga un token de acceso, puedes usarlo para realizar llamadas a una API de Google en nombre de una cuenta de servicio o de usuario determinada si se otorgaron los permisos de acceso que requiere la API. Para ello, incluye el token de acceso en una solicitud a la API con un parámetro de consulta access_token
o un valor Bearer
del encabezado HTTP Authorization
. Cuando sea posible, se recomienda usar el encabezado HTTP, ya que las cadenas de consulta suelen ser visibles en los registros del servidor. En la mayoría de los casos, puedes usar una biblioteca cliente para configurar tus llamadas a las APIs de Google (por ejemplo, cuando llamas a la API de Drive Files).
Puedes probar todas las APIs de Google y ver sus permisos en OAuth 2.0 Playground.
Ejemplos de HTTP GET
Una llamada al extremo
drive.files
(la API de Drive Files) con el encabezado HTTP Authorization: Bearer
podría verse de la siguiente manera. Ten en cuenta que debes especificar tu propio token de acceso:
GET /drive/v2/files HTTP/1.1 Host: www.googleapis.com Authorization: Bearer access_token
Esta es una llamada a la misma API para el usuario autenticado con el parámetro de cadena de consulta access_token
:
GET https://www.googleapis.com/drive/v2/files?access_token=access_token
Ejemplos de curl
Puedes probar estos comandos con la aplicación de línea de comandos de curl
. A continuación, se muestra un ejemplo que usa la opción de encabezado HTTP (preferida):
curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files
O, de forma alternativa, la opción del parámetro de cadena de consulta:
curl https://www.googleapis.com/drive/v2/files?access_token=access_token
Cuándo vencen los tokens de acceso
Los tokens de acceso que emite el servidor de autorización de OAuth 2.0 de Google vencen después de la duración que proporciona el valor de expires_in
. Cuando vence un token de acceso, la aplicación debe generar otro JWT, firmarlo y solicitar otro token de acceso.
Códigos de error de JWT
Campo error |
Campo error_description |
Significado | Cómo resolver el problema |
---|---|---|---|
unauthorized_client |
Unauthorized client or scope in request. |
Si intentas usar la delegación en todo el dominio, la cuenta de servicio no está autorizada en la Consola del administrador del dominio del usuario. |
Asegúrate de que la cuenta de servicio esté autorizada en la página
Delegación en todo el dominio de la Consola del administrador para el usuario en el reclamo (campo) Si bien suele tardar unos minutos, es posible que la autorización demore hasta 24 horas en propagarse a todos los usuarios de tu Cuenta de Google. |
unauthorized_client |
Client is unauthorized to retrieve access tokens using this method, or client not
authorized for any of the scopes requested. |
Se autorizó una cuenta de servicio con la dirección de correo electrónico del cliente en lugar del ID del cliente (numérico) en la Consola del administrador. | En la página Delegación para todo el dominio de la Consola del administrador, quita el cliente y vuelve a agregarlo con el ID numérico. |
access_denied |
(cualquier valor) | Si usas la delegación de todo el dominio, uno o más de los permisos solicitados no están autorizados en la Consola del administrador. |
Asegúrate de que la cuenta de servicio esté autorizada en la página
Delegación para todo el dominio de la Consola del administrador para el usuario en el reclamo (campo) Si bien suele tardar unos minutos, es posible que la autorización demore hasta 24 horas en propagarse a todos los usuarios de tu Cuenta de Google. |
admin_policy_enforced |
(cualquier valor) | La Cuenta de Google no puede autorizar uno o más permisos solicitados debido a las políticas de su administrador de Google Workspace. |
Consulta el artículo de ayuda para administradores de Google Workspace Controla qué apps internas y de terceros acceden a los datos de Google Workspace para obtener más información sobre cómo un administrador puede restringir el acceso a todos los permisos o a los permisos sensibles y restringidos hasta que se otorgue acceso de forma explícita a tu ID de cliente de OAuth. |
invalid_client |
(cualquier valor) |
El cliente de OAuth o el token de JWT no son válidos o están configurados de forma incorrecta. Consulta la descripción del error para obtener más detalles. |
Asegúrate de que el token JWT sea válido y contenga las reclamaciones correctas. Verifica que el cliente OAuth y la cuenta de servicio estén configurados correctamente y que estés usando la dirección de correo electrónico correcta. Verifica que el token JWT sea correcto y se haya emitido para el ID de cliente de la solicitud. |
deleted_client |
(cualquier valor) |
Se borró el cliente de OAuth que se usa para realizar la solicitud. La eliminación puede ocurrir de forma manual o automática en el caso de los clientes no utilizados . Los clientes borrados se pueden restablecer dentro de los 30 días posteriores a la eliminación. Obtén más información. |
Usa un ID de cliente que aún esté activo. |
invalid_grant |
Not a valid email. |
El usuario no existe. | Verifica que la dirección de correo electrónico en el reclamo (campo) sub sea correcta. |
invalid_grant |
|
Por lo general, significa que la hora del sistema local no es correcta. También podría ocurrir si el valor de exp es más de 65 minutos en el futuro desde el valor de iat , o si el valor de exp es inferior al valor de iat . |
Asegúrate de que el reloj del sistema en el que se genera el JWT sea correcto. Si es necesario, sincroniza tu hora con Google NTP. |
invalid_grant |
Invalid JWT Signature. |
La aserción JWT se firma con una clave privada que no está asociada a la cuenta de servicio identificada por el correo electrónico del cliente o la clave que se usó se borró, inhabilitó o venció. Como alternativa, es posible que la aserción de JWT esté codificada de forma incorrecta. Debe estar codificada en Base64, sin saltos de línea ni signos de igual de relleno. |
Decodifica el conjunto de reclamaciones del JWT y verifica que la clave que firmó la aserción esté asociada con la cuenta de servicio. Intenta usar una biblioteca de OAuth proporcionada por Google para asegurarte de que el JWT se genere correctamente. |
invalid_scope |
Invalid OAuth scope or ID token audience provided. |
No se solicitó ningún permiso (lista de permisos vacía) o uno de los permisos solicitados no existe (es decir, no es válido). |
Asegúrate de que el reclamo (campo) Ten en cuenta que la lista de permisos en el reclamo |
disabled_client |
The OAuth client was disabled. |
La clave que se usa para firmar la aserción de JWT está inhabilitada. |
Ve a Google API Consoley, en IAM y administración > Cuentas de servicio, habilita la cuenta de servicio que contiene el "ID de clave" que se usa para firmar la aserción. |
org_internal |
This client is restricted to users within its organization. |
El ID de cliente de OAuth de la solicitud forma parte de un proyecto que limita el acceso a las Cuentas de Google en una organización de Google Cloud específica. |
Usa una cuenta de servicio de la organización para la autenticación. Confirma la configuración del tipo de usuario para tu aplicación de OAuth. |
Anexo: Autorización de cuenta de servicio sin OAuth
Con algunas APIs de Google, puedes realizar llamadas autorizadas a la API usando un JWT firmado directamente como un token del portador, en lugar de un token de acceso de OAuth 2.0. Cuando esto es posible, puedes evitar tener que realizar una solicitud de red al servidor de autorización de Google antes de realizar una llamada a la API.
Si la API a la que deseas llamar tiene una definición de servicio publicada en el repositorio de las APIs de Google en GitHub, puedes realizar llamadas autorizadas a la API con un JWT en lugar de un token de acceso. Para ello, sigue estos pasos:
- Crea una cuenta de servicio como se describió anteriormente. Asegúrate de conservar el archivo JSON que obtienes cuando creas la cuenta.
- Con cualquier biblioteca JWT estándar, como la que se encuentra en jwt.io, crea un JWT con un encabezado y una carga útil como en el siguiente ejemplo:
{ "alg": "RS256", "typ": "JWT", "kid": "abcdef1234567890" } . { "iss": "123456-compute@developer.gserviceaccount.com", "sub": "123456-compute@developer.gserviceaccount.com", "aud": "https://firestore.googleapis.com/", "iat": 1511900000, "exp": 1511903600 }
- Para el campo
kid
en el encabezado, especifica el ID de la clave privada de tu cuenta de servicio. Puedes encontrar este valor en el campoprivate_key_id
del archivo JSON de tu cuenta de servicio. - En los campos
iss
ysub
, especifica la dirección de correo electrónico de tu cuenta de servicio. Puedes encontrar este valor en el campoclient_email
del archivo JSON de tu cuenta de servicio. - Para el campo
aud
, especifica el extremo de la API. Por ejemplo:https://SERVICE.googleapis.com/
- Para el campo
iat
, especifica la hora actual de Unix y, para el campoexp
, especifica la hora exactamente 3,600 segundos después, cuando vencerá el JWT.
Firma el JWT con RSA-256 usando la clave privada que se encuentra en el archivo JSON de tu cuenta de servicio.
Por ejemplo:
Java
Con google-auth-library-java y java-jwt:
import com.google.auth.oauth2.ServiceAccountCredentials; ... GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream("MyProject-1234.json")); PrivateKey privateKey = ((ServiceAccountCredentials) credentials).getPrivateKey(); String privateKeyId = ((ServiceAccountCredentials) credentials).getPrivateKeyId(); long now = System.currentTimeMillis(); try { Algorithm algorithm = Algorithm.RSA256(null, privateKey); String signedJwt = JWT.create() .withKeyId(privateKeyId) .withIssuer("123456-compute@developer.gserviceaccount.com") .withSubject("123456-compute@developer.gserviceaccount.com") .withAudience("https://firestore.googleapis.com/") .withIssuedAt(new Date(now)) .withExpiresAt(new Date(now + 3600 * 1000L)) .sign(algorithm); } catch ...
Python
Con PyJWT:
iat = time.time() exp = iat + 3600 payload = {'iss': '123456-compute@developer.gserviceaccount.com', 'sub': '123456-compute@developer.gserviceaccount.com', 'aud': 'https://firestore.googleapis.com/', 'iat': iat, 'exp': exp} additional_headers = {'kid': PRIVATE_KEY_ID_FROM_JSON} signed_jwt = jwt.encode(payload, PRIVATE_KEY_FROM_JSON, headers=additional_headers, algorithm='RS256')
- Llama a la API con el JWT firmado como token de portador:
GET /v1/projects/abc/databases/123/indexes HTTP/1.1 Authorization: Bearer SIGNED_JWT Host: firestore.googleapis.com
Implementa la Protección integral de la cuenta
Un paso adicional que debes seguir para proteger las cuentas de tus usuarios es implementar la Protección entre cuentas utilizando el servicio de Protección entre cuentas de Google. Este servicio te permite suscribirte a notificaciones de eventos de seguridad que proporcionan información a tu aplicación sobre cambios importantes en la cuenta del usuario. Luego, puedes usar la información para tomar medidas según cómo decidas responder a los eventos.
Estos son algunos ejemplos de los tipos de eventos que el Servicio de Protección entre Cuentas de Google envía a tu app:
-
https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
-
https://schemas.openid.net/secevent/oauth/event-type/token-revoked
-
https://schemas.openid.net/secevent/risc/event-type/account-disabled
Consulta la página Protección de cuentas de usuario con la Protección integral de la cuenta para obtener más información sobre cómo implementar la Protección integral de la cuenta y ver la lista completa de eventos disponibles.