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

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

आपके Chat ऐप्लिकेशन के एंडपॉइंट पर इंटरैक्शन इवेंट भेजने के लिए, Google आपकी सेवा से अनुरोध करता है. यह पुष्टि करने के लिए कि अनुरोध 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 ऐप्लिकेशन की कनेक्शन सेटिंग के पुष्टि करने वाले ऑडियंस फ़ील्ड में एचटीटीपी एंडपॉइंट यूआरएल चुनना होगा. साथ ही, यह पक्का करना होगा कि कॉन्फ़िगरेशन में मौजूद एचटीटीपी एंडपॉइंट यूआरएल, Cloud Function या Cloud Run एंडपॉइंट के यूआरएल से मेल खाता हो.

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

Cloud Functions (1st gen) का इस्तेमाल करने का तरीका यहां बताया गया है:

कंसोल

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 की जगह, अपने Chat ऐप्लिकेशन के फ़ंक्शन का नाम डालें.

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 ऐप्लिकेशन के फ़ंक्शन का नाम डालें.

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

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

अगर आपका एचटीटीपी एंडपॉइंट, IAM पर आधारित पुष्टि करने की सुविधा वाली सेवा (जैसे, 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 पर सेट किया गया है, तो अनुरोध में मौजूद, बियरर की अनुमति वाला टोकन, खुद पर हस्ताक्षर किया गया JSON वेब टोकन (JWT) होता है. इसे chat@system.gserviceaccount.com जारी करता है और इस पर हस्ताक्षर करता है. 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;
}