Verificare le richieste da Google Chat

Per le app Google Chat basate su endpoint HTTP, questa sezione spiega come e verificare che le richieste al tuo endpoint provengano da Chat.

Per inviare eventi di interazione all'app Chat endpoint, Google effettua richieste al tuo servizio. Per verificare che la richiesta sia proveniente da Google, la chat include token di connessione nell'intestazione Authorization di ogni richiesta HTTPS al tuo endpoint. Ad esempio:

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

La stringa AbCdEf123456 nell'esempio precedente è l'autorizzazione di connessione di accesso. Si tratta di un token crittografico prodotto da Google. Il tipo di portante e il valore dell'attributo audience dipende dal tipo di segmento di pubblico per l'autenticazione selezionato durante configurando l'app Chat.

Se hai implementato l'app di chat utilizzando Cloud Functions o Cloud Run, Cloud IAM gestisce automaticamente la verifica dei token. Tu devi solo aggiungere l'account di servizio Google Chat come callback autorizzato. Se la tua app implementa il proprio server HTTP, puoi verificare il token di connessione Utilizzando una libreria client API di Google open source:

Se il token non viene verificato per l'app Chat, deve rispondere alla richiesta con un codice di risposta HTTPS 401 (Unauthorized).

Autentica le richieste utilizzando Cloud Functions o Cloud Run

Se la logica della funzione viene implementata utilizzando Cloud Functions o Cloud Run, devi selezionare App URL nel campo Pubblico di autenticazione dell' App Chat connessione e assicurati che l'URL dell'app nella configurazione corrisponde all'URL della funzione Cloud Functions oppure l'endpoint Cloud Run.

Quindi, devi autorizzare l'account di servizio Google Chat. chat@system.gserviceaccount.com come callback.

I passaggi seguenti mostrano come utilizzare Cloud Functions (1a gen.):

Console

Dopo aver eseguito il deployment della funzione in Google Cloud:

  1. Nella console Google Cloud, vai alla pagina Cloud Functions:

    Vai a Cloud Functions

  2. Nell'elenco Cloud Functions, fai clic sulla casella di controllo accanto personalizzata. Non fare clic sulla funzione in sé.

  3. Fai clic su Autorizzazioni nella parte superiore dello schermo. Riquadro Autorizzazioni si apre.

  4. Fai clic su Aggiungi entità.

  5. Nel campo Nuove entità, inserisci chat@system.gserviceaccount.com.

  6. Seleziona il ruolo Cloud Functions > Invoker di Cloud Functions da Menu a discesa Seleziona un ruolo.

  7. Fai clic su Salva.

gcloud

Usa il 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'

Sostituisci RECEIVING_FUNCTION con il nome del tuo Funzione dell'app di chat.

I passaggi seguenti mostrano come utilizzare i servizi Cloud Functions (2a gen.) o Cloud Run:

Console

Dopo aver eseguito il deployment della funzione o del servizio in Google Cloud:

  1. Nella console Google Cloud, vai alla pagina Cloud Run:

    Vai a Cloud Run

  2. Nell'elenco dei servizi Cloud Run, fai clic sulla casella di controllo accanto personalizzata. Non fare clic sulla funzione in sé.

  3. Fai clic su Autorizzazioni nella parte superiore dello schermo. Riquadro Autorizzazioni si apre.

  4. Fai clic su Aggiungi entità.

  5. Nel campo Nuove entità, inserisci chat@system.gserviceaccount.com.

  6. Seleziona il ruolo Cloud Run > Invoker di Cloud Run dal Menu a discesa Seleziona un ruolo.

  7. Fai clic su Salva.

gcloud

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

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

Sostituisci RECEIVING_FUNCTION con il nome del tuo Funzione dell'app di chat.

Autentica le richieste con un token ID URL app

Se il campo Pubblico autenticazione dell'app Chat l'impostazione di connessione sia impostata su App URL, il token di autorizzazione di connessione nella richiesta è un token OpenID Connect firmato da Google (OIDC) Token ID. Il campo email è impostato su chat@system.gserviceaccount.com. Il campo audience è impostato sull'URL che hai configurato per l'invio da Google Chat richieste alla tua app Chat. Ad esempio, se l'endpoint configurato dell'app di Chat https://example.com/app/, il campo audience nel token ID è https://example.com/app/.

Gli esempi riportati di seguito mostrano come verificare che il token di connessione sia stato emesso da Google Chat e che hanno come target la tua app utilizzando la libreria client OAuth di Google.

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 le richieste con un JWT con numero di progetto

Se il campo Pubblico autenticazione dell'app Chat l'impostazione di connessione è impostata su Project Number, il token di autorizzazione di connessione nella richiesta è un token autofirmato JSON Web Token (JWT), rilasciato e firmato da chat@system.gserviceaccount.com. Il campo audience è impostato sul numero del progetto Google Cloud che hai utilizzato per creare la tua app di Chat. Ad esempio, se Il numero del progetto Cloud dell'app di Chat è 1234567890, il campo audience nel JWT sarà 1234567890.

Gli esempi riportati di seguito mostrano come verificare che il token di connessione sia stato emesso da Google Chat e che hanno come target il tuo progetto utilizzando la libreria client OAuth di Google.

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;
}