Google Chat'ten gelen istekleri doğrulama

HTTP uç noktaları üzerine oluşturulan Google Chat uygulamaları için bu bölümde, uç noktanıza gönderilen isteklerin Chat'ten geldiğini nasıl doğrulayacağınız açıklanmaktadır.

Google, etkileşim etkinliklerini Chat uygulamanızın uç noktasına göndermek için hizmetinize istek gönderir. İsteğin Google'dan geldiğini doğrulamak için Chat, uç noktanıza gönderilen her HTTPS isteğinin Authorization başlığına bir bearer jetonu ekler. Örneğin:

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

Önceki örnekteki AbCdEf123456 dizesi, taşıyıcı yetkilendirme jetonudur. Bu, Google tarafından oluşturulan bir şifreleme jetonudur. Hamiline ait jetonun türü ve audience alanının değeri, Chat uygulamasını yapılandırırken seçtiğiniz kimlik doğrulama kitlesi türüne bağlıdır.

Chat uygulamanızı Cloud Functions veya Cloud Run'u kullanarak uyguladıysanız Cloud IAM, jeton doğrulamasını otomatik olarak yönetir. Google Chat hizmet hesabını yetkili bir başlatıcı olarak eklemeniz yeterlidir. Uygulamanız kendi HTTP sunucusunu uyguluyorsa açık kaynaklı bir Google API istemci kitaplığı kullanarak kimlik bilgisi taşıyıcı jetonunuzu doğrulayabilirsiniz:

Jeton, Chat uygulaması için doğrulanmıyorsa hizmetiniz isteğe bir HTTPS yanıt koduyla 401 (Unauthorized) yanıt vermelidir.

Cloud Functions veya Cloud Run'u kullanarak isteklerin kimliğini doğrulama

İşlev mantığınız Cloud Functions veya Cloud Run kullanılarak uygulandıysa Chat uygulaması bağlantı ayarının Kimlik Doğrulama Kitlesi alanında HTTP uç nokta URL'si seçeneğini belirlemeniz ve yapılandırmadaki HTTP uç nokta URL'sinin, Cloud Functions veya Cloud Run uç noktası URL'sine karşılık geldiğinden emin olmanız gerekir.

Ardından, Google Chat hizmet hesabını chat@system.gserviceaccount.com bir başlatıcı olarak yetkilendirmeniz gerekir.

Aşağıdaki adımlarda, Cloud Functions'ın (1. nesil) nasıl kullanılacağı gösterilmektedir:

Konsol

İşlevinizi Google Cloud'a dağıttıktan sonra:

  1. Google Cloud Console'da Cloud Functions sayfasına gidin:

    Cloud Functions'a git

  2. Cloud Functions listesinde, alıcı işlevin yanındaki onay kutusunu tıklayın. (İşlevin kendisini tıklamayın.)

  3. Ekranın üst kısmındaki İzinler'i tıklayın. İzinler paneli açılır.

  4. Ana hesap ekle'yi tıklayın.

  5. Yeni ana hesaplar alanına chat@system.gserviceaccount.com girin.

  6. Bir rol seçin açılır menüsünden Cloud Functions > Cloud Functions Çağırıcı rolünü seçin.

  7. Kaydet'i tıklayın.

gcloud

gcloud functions add-iam-policy-binding komutunu kullanın:

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

RECEIVING_FUNCTION yerine Chat uygulamanızın işlevinin adını yazın.

Aşağıdaki adımlarda, Cloud Functions (2. nesil) veya Cloud Run hizmetlerinin nasıl kullanılacağı gösterilmektedir:

Konsol

İşlevinizi veya hizmetinizi Google Cloud'a dağıttıktan sonra:

  1. Google Cloud Console'da Cloud Run sayfasına gidin:

    Cloud Run'a git

  2. Cloud Run hizmetleri listesinde, alıcı işlevin yanındaki onay kutusunu tıklayın. (İşlevin kendisini tıklamayın.)

  3. Ekranın üst kısmındaki İzinler'i tıklayın. İzinler paneli açılır.

  4. Ana hesap ekle'yi tıklayın.

  5. Yeni ana hesaplar alanına chat@system.gserviceaccount.com yazın.

  6. Bir rol seçin açılır menüsünden Cloud Run > Cloud Run Çağırıcı rolünü seçin.

  7. Kaydet'i tıklayın.

gcloud

gcloud functions add-invoker-policy-binding komutunu kullanın:

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

RECEIVING_FUNCTION yerine Chat uygulamanızın işlevinin adını yazın.

HTTP isteklerinin kimliğini bir kimlik jetonuyla doğrulama

Chat uygulamasının bağlantı ayarındaki Kimlik Doğrulama Kitlesi alanı HTTP uç nokta URL'si olarak ayarlanmışsa istekteki kimliği taşıyan yetkilendirme jetonu, Google tarafından imzalanmış bir OpenID Connect (OIDC) kimlik jetonudur. email alanı chat@system.gserviceaccount.com olarak ayarlanmış. Kimlik Doğrulama Kitlesi alanı, Google Chat'i Chat uygulamanıza istek göndermesi için yapılandırdığınız URL olarak ayarlanır. Örneğin, Chat uygulamanızın yapılandırılmış uç noktası https://example.com/app/ ise kimlik jetonunda Kimlik Doğrulama Kitlesi alanı https://example.com/app/ olur.

Aşağıdaki örneklerde, Google OAuth istemci kitaplığı kullanılarak kimliği doğrulayıcı jetonun Google Chat tarafından yayınlandığının ve uygulamanızı hedeflediğinin nasıl doğrulanacağı gösterilmektedir.

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

Proje numarası JWT ile isteklerin kimliğini doğrulama

Chat uygulamasının bağlantı ayarının Kimlik Doğrulama Kitlesi alanı Project Number olarak ayarlanmışsa istekteki taşıyıcı yetkilendirme jetonu, chat@system.gserviceaccount.com tarafından verilen ve imzalanan, kendi kendine imzalanmış bir JSON Web Jetonu (JWT) olur. audience alanı, Chat uygulamanızı oluşturmak için kullandığınız Google Cloud proje numarasına ayarlanır. Örneğin, Chat uygulamanızın Cloud proje numarası 1234567890 ise JWT'deki audience alanı 1234567890 olur.

Aşağıdaki örneklerde, Google OAuth istemci kitaplığı kullanılarak kimliği doğrulayıcı jetonun Google Chat tarafından yayınlandığının ve projenizi hedeflediğinin nasıl doğrulanacağı gösterilmektedir.

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