Valider les requêtes provenant de Google Chat

Cette section explique comment effectuer les actions suivantes pour les applications Google Chat basées sur des points de terminaison HTTP : vérifier que les requêtes adressées à votre point de terminaison proviennent bien de Chat.

Pour envoyer des événements d'interaction au réseau point de terminaison, Google envoie des requêtes à votre service. Pour vérifier que la requête provenant de Google, Chat inclut un jeton de support dans l'en-tête Authorization de chaque requête HTTPS adressée à votre point de terminaison. Exemple :

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

La chaîne AbCdEf123456 dans l'exemple précédent correspond à l'autorisation du support à partir d'un jeton d'accès. Il s'agit d'un jeton de chiffrement produit par Google. Le type de support et la valeur audience dépend du type d'audience d'authentification que vous avez sélectionné configurer l'application Chat.

Si vous avez implémenté votre application Chat à l'aide de Cloud ou Cloud Run, Cloud IAM gère automatiquement la validation des jetons. Toi il vous suffit d'ajouter le compte de service Google Chat en tant que demandeur autorisé. Si votre application implémente son propre serveur HTTP, vous pouvez vérifier votre jeton de support à l'aide d'une bibliothèque cliente des API Google Open Source:

Si le jeton n'est pas validé pour l'application Chat, votre doit répondre à la requête avec un code de réponse HTTPS 401 (Unauthorized)

Authentifier les requêtes à l'aide de Cloud Functions ou de Cloud Run

Si votre logique de fonction est implémentée à l'aide de Cloud Functions ou de Cloud Run, vous devez sélectionner App URL dans le champ Authentication Audience (Audience de l'authentification) Application Chat paramètre de connexion et vérifiez que le paramètre l'URL de l'application dans la configuration correspond à l'URL de la fonction Cloud ou point de terminaison Cloud Run.

Vous devez ensuite autoriser le compte de service Google Chat chat@system.gserviceaccount.com en tant que demandeur.

Pour utiliser Cloud Functions (1re génération):

Console

Après avoir déployé votre fonction sur Google Cloud:

  1. Dans la console Google Cloud, accédez à la page Cloud Functions.

    Accéder à Cloud Functions

  2. Dans la liste Cloud Functions, cochez la case située à côté du champ . (Ne cliquez pas directement sur la fonction.)

  3. Cliquez sur Autorisations en haut de l'écran. Le panneau Autorisations s'affiche.

  4. Cliquez sur Ajouter un compte principal.

  5. Dans le champ Nouveaux comptes principaux, saisissez chat@system.gserviceaccount.com.

  6. Sélectionnez le rôle Cloud Functions > Demandeur Cloud Functions du dans le menu déroulant Sélectionnez un rôle.

  7. Cliquez sur Enregistrer.

gcloud

Exécutez la commande gcloud functions add-iam-policy-binding :

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

Remplacez RECEIVING_FUNCTION par le nom de votre Fonction de l'application Chat.

Pour utiliser les services Cloud Functions (2e génération) ou Cloud Run, procédez comme suit:

Console

Après avoir déployé votre fonction ou votre service sur Google Cloud:

  1. Dans la console Google Cloud, accédez à la page Cloud Run:

    Accédez à Cloud Run

  2. Dans la liste des services Cloud Run, cochez la case à côté du champ . (Ne cliquez pas directement sur la fonction.)

  3. Cliquez sur Autorisations en haut de l'écran. Le panneau Autorisations s'affiche.

  4. Cliquez sur Ajouter un compte principal.

  5. Dans le champ Nouveaux comptes principaux, saisissez chat@system.gserviceaccount.com.

  6. Sélectionnez le rôle Cloud Run > Demandeur Cloud Run du dans le menu déroulant Sélectionnez un rôle.

  7. Cliquez sur Enregistrer.

gcloud

Exécutez la commande gcloud functions add-invoker-policy-binding :

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

Remplacez RECEIVING_FUNCTION par le nom de votre Fonction de l'application Chat.

Authentifier les requêtes avec un jeton d'ID d'URL d'application

Si le champ "Audience d'authentification" de l'application Chat paramètre de connexion est défini sur App URL, Le jeton d'autorisation du support inclus dans la requête est un jeton OpenID Connect signé par Google. (OIDC) jeton d'ID. Le champ email est défini sur chat@system.gserviceaccount.com. Le champ audience est défini sur l'URL que vous avez configuré Google Chat pour envoyer à votre application Chat. Par exemple, si le configuré de votre application Chat est https://example.com/app/, le champ audience du jeton d'ID est alors https://example.com/app/

Les exemples suivants montrent comment vérifier que le jeton de support a été émis par Google Chat et ciblant votre application à l'aide de la bibliothèque cliente 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;
}

Authentifier les requêtes avec un JWT de numéro de projet

Si le champ "Audience d'authentification" de l'application Chat paramètre de connexion est défini sur Project Number, le jeton d'autorisation du support dans la requête est un jeton autosigné Jeton Web JSON (JWT), émis et signé par chat@system.gserviceaccount.com. Le champ audience est défini sur le numéro du projet Google Cloud que vous avez utilisé pour créer votre application Chat. Par exemple, si votre Le numéro de projet cloud de l'application Chat est 1234567890, le champ audience du jeton JWT est alors 1234567890.

Les exemples suivants montrent comment vérifier que le jeton de support a été émis par Google Chat et ciblant votre projet à l'aide de la bibliothèque cliente 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;
}