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 punktu końcowego aplikacji Google Chat, Google wysyła do Twojej usługi żądania. Aby potwierdzić, że żądanie pochodzi z Google, Chat zawiera token pełnomocnictwa w nagłówku Authorization każdego żądania HTTPS do Twojego punktu końcowego. Przykład:

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

Ciąg znaków AbCdEf123456 w poprzednim przykładzie to token autoryzacji noszącego. To token kryptograficzny wygenerowany przez Google. Typ tokena biernego i wartość pola audience zależą od typu odbiorców uwierzytelniania wybranego podczas konfigurowania aplikacji Google Chat.

Jeśli aplikacja Google Chat została zaimplementowana za pomocą funkcji Cloud Functions lub Cloud Run, weryfikacja tokena jest obsługiwana automatycznie przez Cloud IAM. Wystarczy, że dodasz konto usługi Google Chat jako autoryzowanego wywołującego. Jeśli Twoja aplikacja implementuje własny serwer HTTP, możesz zweryfikować token pliku bearer za pomocą biblioteki klienta interfejsu API Google open source:

Jeśli token nie zostanie zweryfikowany w aplikacji Google Chat, usługa powinna odpowiedzieć na żądanie kodem odpowiedzi HTTPS401 (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 wybierz adres URL punktu końcowego HTTP i upewnij 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ływacza.

Aby korzystać z Cloud Functions (1 generacji), wykonaj te czynności:

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 funkcji Cloud Functions 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. W menu Wybierz rolę wybierz rolę Cloud Functions > Wywołujący Cloud Functions.

  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ą funkcji aplikacji Chat.

Te czynności pokazują, jak korzystać z usług Cloud Functions (2 generacji) lub Cloud Run:

Konsola

Po wdrożeniu funkcji lub usługi do 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. W menu Wybierz rolę wybierz rolę Cloud Run > Wywołujący Cloud Run.

  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ą funkcji aplikacji Chat.

Uwierzytelnianie żądań HTTP za pomocą tokena identyfikacyjnego

Jeśli pole „Authentication Audience” (Grupa odbiorców uwierzytelniania) w ustawieniu połączenia aplikacji Google Chat ma wartość HTTP endpoint URL, token autoryzacji biernego w żądaniu to podpisany przez Google token identyfikatora OpenID Connect (OIDC). W polu email ustawiono wartość 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 ID będzie zawierać wartość https://example.com/app/.

Ta metoda uwierzytelniania jest zalecana, jeśli punkt końcowy HTTP nie jest hostowany w usłudze, która obsługuje uwierzytelnianie oparte na IAM (np. Cloud Functions lub Cloud Run). W przypadku tej metody usługa HTTP potrzebuje informacji o adresie URL punktu końcowego, w którym jest uruchomiona, ale nie potrzebuje informacji o numerze projektu Cloud.

Poniższe przykłady pokazują, jak sprawdzić, czy token tożsamości został wydany przez Google Chat i czy jest kierowany do Twojej aplikacji za pomocą biblioteki klienta OAuth 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;
}

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

Jeśli pole „Authentication Audience” (Grupa odbiorców uwierzytelniania) w ustawieniu połączenia aplikacji Chat ma wartość Project Number, token autoryzacji noszącego w żądaniu jest samodzielnie podpisanym tokenem internetowym JSON (JWT), wydanym i podpisanym przez chat@system.gserviceaccount.com. Pole audience jest ustawione na numer projektu Google Cloud, którego użyto do utworzenia aplikacji Google Chat. Jeśli na przykład numer projektu Google Cloud aplikacji Google Chat to 1234567890, pole audience w JWT to 1234567890.

Ta metoda uwierzytelniania jest zalecana tylko wtedy, gdy do weryfikacji żądań zamiast adresu URL punktu końcowego HTTP wolisz używać numeru projektu Cloud. Możesz to zrobić na przykład, jeśli chcesz zmienić adres URL punktu końcowego, zachowując ten sam numer projektu Cloud, lub jeśli chcesz używać tego samego punktu końcowego w przypadku wielu numerów projektów Cloud i porównywać pole audience z listą numerów projektów Cloud.

Poniższe przykłady pokazują, jak sprawdzić, czy token pliku bearer został wydany przez Google Chat i skierowany do Twojego projektu za pomocą biblioteki klienta OAuth 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;
}