Verifica las solicitudes de Google Chat

En el caso de las apps de Google Chat compiladas en extremos HTTP, en esta sección se explica cómo verificarás que las solicitudes a tu extremo provengan de Chat.

Para enviar eventos de interacción al entorno extremo, Google realiza solicitudes a tu servicio. Para verificar que la solicitud esté provenientes de Google, Chat incluye un token del portador en el encabezado Authorization de cada solicitud HTTPS a tu extremo. Por ejemplo:

POST
Host: yourappurl.com
Authorization: Bearer AbCdEf123456
Content-Type: application/json
User-Agent: Google-Dynamite

La cadena AbCdEf123456 del ejemplo anterior es la autorización del portador. token. Este es un token criptográfico producido por Google. El tipo de portador token y el valor del audience dependen del tipo de público de autenticación que selecciones al momento cómo configurar la app de Chat

Si implementaste la app de Chat con Cloud Functions o Cloud Run, Cloud IAM controla la verificación de tokens automáticamente. Tú solo necesito agregar la cuenta de servicio de Google Chat como un invocador autorizado. Si tu app implementa su propio servidor HTTP, puedes verificar tu token del portador Con una biblioteca cliente de la API de Google de código abierto:

Si no se verifica con el token para la app de Chat, tu servicio debe responder a la solicitud con un código de respuesta HTTPS 401 (Unauthorized)

Autentica solicitudes con Cloud Functions o Cloud Run

Si la lógica de tu función se implementa con Cloud Functions o Cloud Run, debes seleccionar App URL en el campo Authentication Audience de la App de Chat configuración de conexión y asegúrate de que la URL de la app en la configuración corresponde a la URL de la Cloud Function extremo de Cloud Run.

Luego, debes autorizar la cuenta de servicio de Google Chat chat@system.gserviceaccount.com como invocador

En los siguientes pasos, se muestra cómo usar Cloud Functions (1a gen.):

Console

Después de implementar la función en Google Cloud, sigue estos pasos:

  1. En la consola de Google Cloud, ve a la página Cloud Functions.

    Ir a Cloud Functions

  2. En la lista de Cloud Functions, haz clic en la casilla de verificación junto al nombre . (No hagas clic en la función).

  3. Haz clic en Permisos en la parte superior de la pantalla. Se abrirá el panel Permisos.

  4. Haz clic en Agregar principal.

  5. En el campo Principales nuevas, ingresa chat@system.gserviceaccount.com.

  6. Selecciona el rol Cloud Functions > Invocador de Cloud Functions desde la El menú desplegable Selecciona un rol.

  7. Haz clic en Guardar.

gcloud

Usa el comando gcloud functions add-iam-policy-binding:

gcloud functions add-iam-policy-binding RECEIVING_FUNCTION \
  --member='serviceAccount:chat@system.gserviceaccount.com' \
  --role='roles/cloudfunctions.invoker'

Reemplaza RECEIVING_FUNCTION por el nombre de tu función de la app de Chat.

En los siguientes pasos, se muestra cómo usar los servicios de Cloud Functions (2a gen.) o de Cloud Run:

Console

Después de implementar tu función o servicio en Google Cloud, haz lo siguiente:

  1. En la consola de Google Cloud, ve a la página de Cloud Run:

    Ir a Cloud Run

  2. En la lista de servicios de Cloud Run, haz clic en la casilla de verificación junto al nombre . (No hagas clic en la función).

  3. Haz clic en Permisos en la parte superior de la pantalla. Se abrirá el panel Permisos.

  4. Haz clic en Agregar principal.

  5. En el campo Principales nuevas, ingresa chat@system.gserviceaccount.com.

  6. Selecciona el rol Cloud Run > Invocador de Cloud Run desde la El menú desplegable Selecciona un rol.

  7. Haz clic en Guardar.

gcloud

Usa el comando gcloud functions add-invoker-policy-binding:

gcloud functions add-invoker-policy-binding RECEIVING_FUNCTION \
  --member='serviceAccount:chat@system.gserviceaccount.com'

Reemplaza RECEIVING_FUNCTION por el nombre de tu función de la app de Chat.

Autentica solicitudes con un token de ID de URL de la app

Si el campo Authentication Audience de la app de Chat La configuración de conexión está establecida en App URL, El token de autorización del portador en la solicitud es un OpenID Connect firmado por Google (OIDC) token de ID. El campo email se establece en chat@system.gserviceaccount.com. El campo audience se establece en la URL que configuraste para que envíe Google Chat las solicitudes a la app de Chat. Por ejemplo, si el extremo configurado de tu app de Chat https://example.com/app/, el campo audience en el token de ID se https://example.com/app/

En los siguientes ejemplos, se muestra cómo verificar que una entidad emisora haya emitido el token del portador Google Chat y se orienta a tu app con la biblioteca cliente de Google OAuth.

Java

java/basic-app/src/main/java/com/google/chat/app/basic/App.java
String CHAT_ISSUER = "chat@system.gserviceaccount.com";
JsonFactory factory = JacksonFactory.getDefaultInstance();

GoogleIdTokenVerifier verifier =
    new GoogleIdTokenVerifier.Builder(new ApacheHttpTransport(), factory)
        .setAudience(Collections.singletonList(AUDIENCE))
        .build();

GoogleIdToken idToken = GoogleIdToken.parse(factory, bearer);
return idToken != null
    && verifier.verify(idToken)
    && idToken.getPayload().getEmailVerified()
    && idToken.getPayload().getEmail().equals(CHAT_ISSUER);

Python

python/basic-app/main.py
# Bearer Tokens received by apps will always specify this issuer.
CHAT_ISSUER = 'chat@system.gserviceaccount.com'

try:
    # Verify valid token, signed by CHAT_ISSUER, intended for a third party.
    request = requests.Request()
    token = id_token.verify_oauth2_token(bearer, request, AUDIENCE)
    return token['email'] == CHAT_ISSUER

except:
    return False

Node.js

node/basic-app/index.js
// Bearer Tokens received by apps will always specify this issuer.
const chatIssuer = 'chat@system.gserviceaccount.com';

// Verify valid token, signed by chatIssuer, intended for a third party.
try {
  const ticket = await client.verifyIdToken({
    idToken: bearer,
    audience: audience
  });
  return ticket.getPayload().email_verified
      && ticket.getPayload().email === chatIssuer;
} catch (unused) {
  return false;
}

Autentica solicitudes con un JWT de número de proyecto

Si el campo Authentication Audience de la app de Chat La configuración de conexión se establece en Project Number, el token de autorización del portador en la solicitud es un token autofirmado Token web JSON (JWT), emitido y firmado por chat@system.gserviceaccount.com. El campo audience se establece con el número de proyecto de Google Cloud que usaste. para compilar tu app de Chat. Por ejemplo, si tu El número de proyecto de Cloud de la app de Chat es 1234567890, luego el campo audience en el JWT es 1234567890.

En los siguientes ejemplos, se muestra cómo verificar que una entidad emisora haya emitido el token del portador Google Chat y se orienta a tu proyecto con la biblioteca cliente de Google OAuth.

Java

java/basic-app/src/main/java/com/google/chat/app/basic/App.java
String CHAT_ISSUER = "chat@system.gserviceaccount.com";
JsonFactory factory = JacksonFactory.getDefaultInstance();

GooglePublicKeysManager keyManagerBuilder =
    new GooglePublicKeysManager.Builder(new ApacheHttpTransport(), factory)
        .setPublicCertsEncodedUrl(
            "https://www.googleapis.com/service_accounts/v1/metadata/x509/" + CHAT_ISSUER)
        .build();

GoogleIdTokenVerifier verifier =
    new GoogleIdTokenVerifier.Builder(keyManagerBuilder).setIssuer(CHAT_ISSUER).build();

GoogleIdToken idToken = GoogleIdToken.parse(factory, bearer);
return idToken != null
    && verifier.verify(idToken)
    && idToken.verifyAudience(Collections.singletonList(AUDIENCE))
    && idToken.verifyIssuer(CHAT_ISSUER);

Python

python/basic-app/main.py
# Bearer Tokens received by apps will always specify this issuer.
CHAT_ISSUER = 'chat@system.gserviceaccount.com'

try:
    # Verify valid token, signed by CHAT_ISSUER, intended for a third party.
    request = requests.Request()
    certs_url = 'https://www.googleapis.com/service_accounts/v1/metadata/x509/' + CHAT_ISSUER
    token = id_token.verify_token(bearer, request, AUDIENCE, certs_url)
    return token['iss'] == CHAT_ISSUER

except:
    return False

Node.js

node/basic-app/index.js
// Bearer Tokens received by apps will always specify this issuer.
const chatIssuer = 'chat@system.gserviceaccount.com';

// Verify valid token, signed by CHAT_ISSUER, intended for a third party.
try {
  const response = await fetch('https://www.googleapis.com/service_accounts/v1/metadata/x509/' + chatIssuer);
  const certs = await response.json();
  await client.verifySignedJwtWithCertsAsync(
    bearer, certs, audience, [chatIssuer]);
  return true;
} catch (unused) {
  return false;
}