Weryfikowanie próśb z Google Chat

W przypadku aplikacji Google Chat utworzonych na punktach końcowych HTTP ta sekcja wyjaśnia, jak sprawdź, czy żądania wysyłane do punktu końcowego pochodzą z Google Chat.

Aby wysyłać zdarzenia interakcji do to Google wysyła żądania do Twojej usługi. Aby sprawdzić, czy prośba jest pochodzących od Google, token okaziciela w nagłówku Authorization każdego żądania HTTPS wysyłanego do punktu końcowego. Przykład:

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

Ciąg AbCdEf123456 w poprzednim przykładzie to autoryzacja okaziciela token. To token kryptograficzny wygenerowany przez Google. Typ okaziciela token i wartość parametru audience zależy od typu grupy odbiorców uwierzytelniania, wybranej podczas skonfigurować aplikację Google Chat.

Jeśli Twoja aplikacja Google Chat została wdrożona za pomocą Google Cloud lub Cloud Run, Cloud IAM automatycznie obsługuje weryfikację tokenów. Ty wystarczy dodać konto usługi Google Chat jako autoryzowany wywołujący. Jeśli Twoja aplikacja ma własny serwer HTTP, możesz zweryfikować token okaziciela za pomocą biblioteki klienta interfejsów API Google typu open source:

Jeśli token nie zostanie zweryfikowany dla aplikacji Google Chat, usługa powinna odpowiadać na żądanie kodem odpowiedzi HTTPS 401 (Unauthorized)

Uwierzytelnianie żądań za pomocą Cloud Functions lub Cloud Run

Jeśli logikę funkcji wdrożysz za pomocą Cloud Functions lub Cloud Run, musi wybrać App URL w polu Authentication Audience (Odbiorcy uwierzytelniania) w aplikacja do obsługi czatu ustawienia połączenia i upewnij się, że URL aplikacji w konfiguracji odpowiada adresowi URL funkcji w Cloud Functions lub Punkt końcowy Cloud Run.

Następnie musisz autoryzować konto usługi Google Chat chat@system.gserviceaccount.com jako wywołującego.

Poniżej znajdziesz instrukcje korzystania z Cloud Functions (1 generacji):

Konsola

Po wdrożeniu funkcji w Google Cloud:

  1. W konsoli Google Cloud otwórz stronę Cloud Functions:

    Otwórz Cloud Functions

  2. Na liście Cloud Functions zaznacz pole wyboru obok . Nie klikaj samej funkcji.

  3. Kliknij Uprawnienia u góry ekranu. Panel Uprawnienia zostanie otwarte.

  4. Kliknij Dodaj podmiot zabezpieczeń.

  5. W polu Nowe podmioty zabezpieczeń wpisz chat@system.gserviceaccount.com.

  6. Wybierz rolę Cloud Functions > Wywołujący Cloud Functions z narzędzia Menu Wybierz rolę.

  7. Kliknij Zapisz.

gcloud

Użyj polecenia gcloud functions add-iam-policy-binding:

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

Zastąp RECEIVING_FUNCTION nazwą swojego Funkcja aplikacji Google Chat.

Poniższe kroki pokazują, jak korzystać z usług Cloud Functions (2 generacji) lub Cloud Run:

Konsola

Po wdrożeniu funkcji lub usługi w Google Cloud:

  1. W konsoli Google Cloud otwórz stronę Cloud Run:

    Otwórz Cloud Run

  2. Na liście usług Cloud Run zaznacz pole wyboru obok otrzymanego . Nie klikaj samej funkcji.

  3. Kliknij Uprawnienia u góry ekranu. Panel Uprawnienia zostanie otwarte.

  4. Kliknij Dodaj podmiot zabezpieczeń.

  5. W polu Nowe podmioty zabezpieczeń wpisz chat@system.gserviceaccount.com.

  6. Wybierz rolę Cloud Run > Wywołujący Cloud Run z Menu Wybierz rolę.

  7. Kliknij Zapisz.

gcloud

Użyj polecenia gcloud functions add-invoker-policy-binding:

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

Zastąp RECEIVING_FUNCTION nazwą swojego Funkcja aplikacji Google Chat.

Uwierzytelnianie żądań za pomocą tokena identyfikatora adresu URL aplikacji

Jeśli w polu Authentication Audience (Odbiorcy uwierzytelniania) aplikacji Google Chat ustawienie połączenia ma wartość App URL, token autoryzacji okaziciela w żądaniu to podpisany przez Google identyfikator OpenID Connect Token tożsamości (OIDC). Pole email jest ustawione na chat@system.gserviceaccount.com. Pole audience jest ustawione na adres URL skonfigurowany do wysyłania wiadomości w Google Chat żądań wysyłanych do aplikacji Google Chat. Na przykład, jeśli plik skonfigurowany punkt końcowy aplikacji Google Chat to https://example.com/app/, pole audience w tokenie identyfikatora to https://example.com/app/

Z poniższych przykładów dowiesz się, jak sprawdzić, czy token okaziciela został wystawiony przez Google Chat i kierowane na Twoją aplikację za pomocą biblioteki klienta 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;
}

Uwierzytelnianie żądań za pomocą tokena JWT z numerem projektu

Jeśli w polu Authentication Audience (Odbiorcy uwierzytelniania) aplikacji Google Chat ustawienie połączenia ma wartość Project Number, token autoryzacji okaziciela w żądaniu jest samodzielnie podpisany Token internetowy JSON (JWT), wydane i podpisane przez chat@system.gserviceaccount.com. W polu audience jest ustawiony numer używanego przez Ciebie projektu Google Cloud aby stworzyć aplikację Google Chat. Jeśli na przykład plik Numer projektu Cloud aplikacji do obsługi czatu to 1234567890, to pole audience w tokenie JWT zawiera 1234567890.

Z poniższych przykładów dowiesz się, jak sprawdzić, czy token okaziciela został wystawiony przez Google Chat i ustaw kierowanie na Twój projekt za pomocą biblioteki klienta 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;
}