Se establece una Bearer Token
en el encabezado Authorization
de cada solicitud HTTP de acción en la app. Por ejemplo:
POST /approve?expenseId=abc123 HTTP/1.1
Host: your-domain.com
Authorization: Bearer AbCdEf123456
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/1.0 (KHTML, like Gecko; Gmail Actions)
confirmed=Approved
La cadena "AbCdEf123456" en el ejemplo anterior es el token de autorización del portador.
Este es un token criptográfico producido por Google.
Todos los tokens del portador enviados con acciones tienen el campo azp
(parte autorizada), como
gmail@system.gserviceaccount.com
, con el campo audience
que especifica el dominio del remitente como una URL del formulario.
https://
Por ejemplo, si el correo electrónico es de noreply@example.com
, la
el público es https://example.com
.
Si usas tokens del portador, verifica que la solicitud provenga de Google
y está destinada al dominio del remitente. Si no se verifica el token, el servicio debería
responde a la solicitud con un código de respuesta HTTP 401 (Unauthorized)
.
Los tokens del portador son parte del estándar OAuth V2 y son ampliamente adoptados por las APIs de Google.
Verificación de los tokens del portador
Se recomienda que los servicios usen la biblioteca cliente de la API de Google de código abierto para verificar los tokens del portador:
- Java: https://github.com/google/google-api-java-client
- Python: https://github.com/google/google-api-python-client
Java
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
import com.google.api.client.http.apache.ApacheHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
public class TokenVerifier {
// Bearer Tokens from Gmail Actions will always be issued to this authorized party.
private static final String GMAIL_AUTHORIZED_PARTY = "gmail@system.gserviceaccount.com";
// Intended audience of the token, based on the sender's domain
private static final String AUDIENCE = "https://example.com";
public static void main(String[] args) throws GeneralSecurityException, IOException {
// Get this value from the request's Authorization HTTP header.
// For example, for "Authorization: Bearer AbCdEf123456" use "AbCdEf123456"
String bearerToken = "AbCdEf123456";
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(new ApacheHttpTransport(), new JacksonFactory())
.setAudience(Collections.singletonList(AUDIENCE))
.build();
GoogleIdToken idToken = verifier.verify(bearerToken);
if (idToken == null || !idToken.getPayload().getAuthorizedParty().equals(GMAIL_AUTHORIZED_PARTY)) {
System.out.println("Invalid token");
System.exit(-1);
}
// Token originates from Google and is targeted to a specific client.
System.out.println("The token is valid");
System.out.println("Token details:");
System.out.println(idToken.getPayload().toPrettyString());
}
}
Python
import sys
from oauth2client import client
# Bearer Tokens from Gmail Actions will always be issued to this authorized party.
GMAIL_AUTHORIZED_PARTY = 'gmail@system.gserviceaccount.com'
# Intended audience of the token, based on the sender's domain
AUDIENCE = 'https://example.com'
try:
# Get this value from the request's Authorization HTTP header.
# For example, for "Authorization: Bearer AbCdEf123456" use "AbCdEf123456"
bearer_token = 'AbCdEf123456'
# Verify valid token, signed by google.com, intended for a third party.
token = client.verify_id_token(bearer_token, AUDIENCE)
print('Token details: %s' % token)
if token['azp'] != GMAIL_AUTHORIZED_PARTY:
sys.exit('Invalid authorized party')
except:
sys.exit('Invalid token')
# Token originates from Google and is targeted to a specific client.
print('The token is valid')