Google Chat से मिले अनुरोधों की पुष्टि करना

एचटीटीपी एंडपॉइंट पर बनाए गए Google Chat ऐप्लिकेशन के लिए, इस सेक्शन में यह पुष्टि करने का तरीका बताया गया है कि आपके एंडपॉइंट पर किए गए अनुरोध, Chat से किए गए हैं.

Google, आपके Chat ऐप्लिकेशन के एंडपॉइंट पर इंटरैक्शन इवेंट भेजने के लिए, आपकी सेवा से अनुरोध करता है. यह पुष्टि करने के लिए कि अनुरोध Google से आ रहा है, Chat आपके एंडपॉइंट को किए गए हर एचटीटीपीएस अनुरोध के Authorization हेडर में बेयरर टोकन शामिल करता है. उदाहरण के लिए:

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

पिछले उदाहरण में, स्ट्रिंग AbCdEf123456, बियरर ऑथराइज़ेशन टोकन है. यह Google का बनाया हुआ क्रिप्टोग्राफ़िक टोकन है. बियरर टोकन का टाइप और audience फ़ील्ड की वैल्यू, इस बात पर निर्भर करती है कि आपने Chat ऐप्लिकेशन को कॉन्फ़िगर करते समय, किस तरह की पुष्टि करने वाले ऑडियंस को चुना था.

अगर आपने Cloud Functions या Cloud Run का इस्तेमाल करके Chat ऐप्लिकेशन को लागू किया है, तो Cloud IAM टोकन की पुष्टि अपने-आप करता है. आपको सिर्फ़ Google Chat के सेवा खाते को, अनुमति पा चुके इनवोकर के तौर पर जोड़ना होगा. अगर आपका ऐप्लिकेशन अपना एचटीटीपी सर्वर लागू करता है, तो ओपन सोर्स Google API क्लाइंट लाइब्रेरी का इस्तेमाल करके, अपने बियरर टोकन की पुष्टि की जा सकती है:

अगर Chat ऐप्लिकेशन के लिए टोकन की पुष्टि नहीं होती है, तो आपकी सेवा को अनुरोध का जवाब एचटीटीपीएस रिस्पॉन्स कोड 401 (Unauthorized) के साथ देना चाहिए.

Cloud Functions या Cloud Run का इस्तेमाल करके अनुरोधों की पुष्टि करना

अगर आपके फ़ंक्शन लॉजिक को Cloud Functions या Cloud Run का इस्तेमाल करके लागू किया गया है, तो आपको Chat ऐप्लिकेशन की कनेक्शन सेटिंग के Authentication Audience फ़ील्ड में HTTP endpoint URL चुनना होगा. साथ ही, यह पक्का करना होगा कि कॉन्फ़िगरेशन में मौजूद HTTP endpoint URL, Cloud Function या Cloud Run एंडपॉइंट के यूआरएल से मेल खाता हो.

इसके बाद, आपको Google Chat सेवा खाते chat@system.gserviceaccount.com को इनवॉकर के तौर पर अनुमति देनी होगी.

Cloud Functions (पहली जनरेशन) का इस्तेमाल करने का तरीका यहां बताया गया है:

कंसोल

Google Cloud पर फ़ंक्शन डिप्लॉय करने के बाद:

  1. Google Cloud Console में, Cloud Functions पेज पर जाएं:

    Cloud Functions पर जाएं

  2. Cloud Functions की सूची में, डेटा पाने वाले फ़ंक्शन के बगल में मौजूद चेकबॉक्स पर क्लिक करें. (फ़ंक्शन पर क्लिक न करें.)

  3. स्क्रीन के सबसे ऊपर, अनुमतियां पर क्लिक करें. अनुमतियां पैनल खुलता है.

  4. प्रिंसिपल जोड़ें पर क्लिक करें.

  5. नए प्रिंसिपल फ़ील्ड में, chat@system.gserviceaccount.com डालें.

  6. भूमिका चुनें ड्रॉप-डाउन मेन्यू से, Cloud Functions > Cloud Functions Invoker भूमिका चुनें.

  7. सेव करें पर क्लिक करें.

gcloud

gcloud functions add-iam-policy-binding निर्देश का इस्तेमाल करें:

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

RECEIVING_FUNCTION की जगह, अपने चैट ऐप्लिकेशन के फ़ंक्शन का नाम डालें.

यहां Cloud Functions (दूसरी जनरेशन) या Cloud Run सेवाओं का इस्तेमाल करने का तरीका बताया गया है:

कंसोल

Google Cloud पर फ़ंक्शन या सेवा को डिप्लॉय करने के बाद:

  1. Google Cloud Console में, Cloud Run पेज पर जाएं:

    Cloud Run पर जाएं

  2. Cloud Run सेवाओं की सूची में, डेटा पाने वाले फ़ंक्शन के बगल में मौजूद चेकबॉक्स पर क्लिक करें. (फ़ंक्शन पर क्लिक न करें.)

  3. स्क्रीन के सबसे ऊपर, अनुमतियां पर क्लिक करें. अनुमतियां पैनल खुलता है.

  4. प्रिंसिपल जोड़ें पर क्लिक करें.

  5. नए प्रिंसिपल फ़ील्ड में, chat@system.gserviceaccount.com डालें.

  6. भूमिका चुनें ड्रॉप-डाउन मेन्यू से, Cloud Run > Cloud Run Invoker भूमिका चुनें.

  7. सेव करें पर क्लिक करें.

gcloud

gcloud functions add-invoker-policy-binding निर्देश का इस्तेमाल करें:

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

RECEIVING_FUNCTION की जगह, अपने चैट ऐप्लिकेशन के फ़ंक्शन का नाम डालें.

आईडी टोकन की मदद से एचटीटीपी अनुरोधों की पुष्टि करना

अगर Chat ऐप्लिकेशन की कनेक्शन सेटिंग में मौजूद, Authentication Audience फ़ील्ड को HTTP endpoint URL पर सेट किया गया है, तो अनुरोध में मौजूद Bearer Authorization Token, Google के हस्ताक्षर वाला OpenID Connect (OIDC) आईडी टोकन होता है. email फ़ील्ड को chat@system.gserviceaccount.com पर सेट किया गया है. पुष्टि करने वाले ऑडियंस फ़ील्ड को उस यूआरएल पर सेट किया जाता है जिसे आपने Google Chat को कॉन्फ़िगर किया है, ताकि वह आपके Chat ऐप्लिकेशन को अनुरोध भेज सके. उदाहरण के लिए, अगर आपके Chat ऐप्लिकेशन का कॉन्फ़िगर किया गया एंडपॉइंट https://example.com/app/ है, तो आईडी टोकन में पुष्टि करने वाले ऑडियंस फ़ील्ड https://example.com/app/ होगा.

अगर आपका एचटीटीपी एंडपॉइंट, आईएएम पर आधारित पुष्टि करने की सुविधा देने वाली सेवा (जैसे कि Cloud Functions या Cloud Run) पर होस्ट नहीं किया गया है, तो पुष्टि करने के इस तरीके का इस्तेमाल करने का सुझाव दिया जाता है. इस तरीके का इस्तेमाल करने पर, आपकी एचटीटीपी सेवा को उस एंडपॉइंट के यूआरएल की जानकारी चाहिए जहां वह चल रही है. हालांकि, उसे Cloud प्रोजेक्ट नंबर की जानकारी की ज़रूरत नहीं होती.

यहां दिए गए उदाहरणों में, यह पुष्टि करने का तरीका बताया गया है कि Google Chat ने बेयरर टोकन जारी किया है और 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;
}

प्रोजेक्ट नंबर वाले JWT की मदद से अनुरोधों की पुष्टि करना

अगर Chat ऐप्लिकेशन की कनेक्शन सेटिंग में, पुष्टि करने वाले ऑडियंस फ़ील्ड को Project Number पर सेट किया गया है, तो अनुरोध में मौजूद बियरर ऑथराइज़ेशन टोकन, chat@system.gserviceaccount.com के ज़रिए जारी किया गया और हस्ताक्षर किया गया, खुद पर हस्ताक्षर किया गया JSON Web Token (JWT) होता है. audience फ़ील्ड को उस Google Cloud प्रोजेक्ट नंबर पर सेट किया जाता है जिसका इस्तेमाल आपने Chat ऐप्लिकेशन बनाने के लिए किया था. उदाहरण के लिए, अगर आपके Chat ऐप्लिकेशन का Cloud प्रोजेक्ट नंबर 1234567890 है, तो JWT में audience फ़ील्ड 1234567890 होगा.

पुष्टि करने के इस तरीके का इस्तेमाल सिर्फ़ तब करें, जब आपको एचटीटीपी एंडपॉइंट यूआरएल के बजाय, Cloud प्रोजेक्ट नंबर का इस्तेमाल करके अनुरोधों की पुष्टि करनी हो. उदाहरण के लिए, अगर आपको समय के साथ एंडपॉइंट यूआरएल बदलना है, लेकिन Cloud प्रोजेक्ट नंबर वही रखना है. इसके अलावा, अगर आपको कई Cloud प्रोजेक्ट नंबर के लिए एक ही एंडपॉइंट का इस्तेमाल करना है और audience फ़ील्ड की तुलना Cloud प्रोजेक्ट नंबर की सूची से करनी है.

नीचे दिए गए उदाहरणों में, यह पुष्टि करने का तरीका बताया गया है कि Google Chat ने बियरर टोकन जारी किया है और 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;
}