Weryfikowanie próśb z Google Chat

W tej sekcji znajdziesz instrukcje weryfikacji, czy żądania wysyłane do punktu końcowego pochodzą z Google Chat. Dotyczy to aplikacji Google Chat opartych na punktach końcowych HTTP.

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)

uwierzytelniać żądania za pomocą Cloud Functions lub Cloud Run;

Jeśli logika funkcji jest implementowana za pomocą Cloud Functions lub Cloud Run, w polu Authentication Audienceustawieniu połączenia aplikacji Google Chat musisz wybrać adres URL punktu końcowego HTTP i upewnić się, że adres URL punktu końcowego HTTP w konfiguracji odpowiada adresowi URL punktu końcowego Cloud Functions lub 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 do 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. U góry ekranu kliknij Uprawnienia. Otworzy się panel Uprawnienia.

  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 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.

Aby korzystać z usług Cloud Functions (2 generacji) lub Cloud Run, wykonaj te czynności:

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 kliknij pole wyboru obok funkcji odbierającej. Nie klikaj samej funkcji.

  3. U góry ekranu kliknij Uprawnienia. Otworzy się panel Uprawnienia.

  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ń HTTP za pomocą tokena identyfikacyjnego

Jeśli w polu Authentication Audience (Odbiorcy uwierzytelniania) aplikacji Google Chat ustawienie połączenia ma wartość Adres URL punktu końcowego HTTP, token autoryzacji okaziciela w żądaniu to podpisany przez Google identyfikator OpenID Connect (OIDC) token identyfikatora. Pole email jest ustawione na chat@system.gserviceaccount.com. Pole Authentication Audience (Odbiorcy uwierzytelniania) zawiera adres URL skonfigurowany w Google Chat do wysyłania żądań do aplikacji Chat. Jeśli na przykład skonfigurowany punkt końcowy aplikacji Chat to https://example.com/app/, pole Authentication Audience (Odbiorcy uwierzytelniania) w tokenie identyfikacyjnym 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;
}