Google Chat থেকে অনুরোধ যাচাই করুন

HTTP এন্ডপয়েন্টের উপর ভিত্তি করে তৈরি Google Chat অ্যাপগুলির জন্য, আপনার এন্ডপয়েন্টে পাঠানো অনুরোধগুলি Chat থেকেই আসছে কিনা, তা কীভাবে যাচাই করবেন, এই বিভাগে তা ব্যাখ্যা করা হয়েছে।

To dispatch interaction events to your Chat app's endpoint, Google makes requests to your service. To verify that the request is coming from Google, Chat includes a bearer token in the Authorization header of every HTTPS request to your endpoint. For example:

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

The string AbCdEf123456 in the preceding example is the bearer authorization token. This is a cryptographic token produced by Google. The type of the bearer token and the value of the audience field depend on the type of authentication audience you selected when configuring the Chat app .

If you've implemented your Chat app using Cloud Run functions, Cloud IAM handles token verification automatically. You must add the Google Chat service account as an authorized invoker. If your app implements its own HTTP server, you can verify your bearer token using an open source Google API client library :

যদি চ্যাট অ্যাপের জন্য টোকেনটি যাচাই করা না যায়, তাহলে আপনার পরিষেবাটির উচিত অনুরোধটির জবাবে একটি HTTPS রেসপন্স কোড 401 (Unauthorized) পাঠানো।

ক্লাউড রান ফাংশন ব্যবহার করে অনুরোধগুলি প্রমাণীকরণ করুন

If your function logic is implemented using Cloud Run functions, you must select HTTP endpoint URL in the Authentication Audience field of the Chat app connection setting and make sure that the HTTP endpoint URL in the configuration corresponds to the URL of the Cloud Run function endpoint.

এরপর, নিম্নলিখিত ধাপগুলো অনুসরণ করে আপনাকে chat@system.gserviceaccount.com গুগল চ্যাট পরিষেবা অ্যাকাউন্টটিকে একজন আহ্বানকারী হিসেবে অনুমোদন করতে হবে:

কনসোল

গুগল ক্লাউডে আপনার ফাংশন বা পরিষেবা স্থাপন করার পরে:

  1. গুগল ক্লাউড কনসোলে, ক্লাউড রান পৃষ্ঠায় যান:

    ক্লাউড রানে যান

  2. ক্লাউড রান সার্ভিসেস লিস্টে, রিসিভিং ফাংশনের পাশের চেকবক্সে ক্লিক করুন। (ফাংশনটিতে সরাসরি ক্লিক করবেন না।)

  3. স্ক্রিনের উপরের দিকে থাকা পারমিশন (Permissions)- এ ক্লিক করুন। পারমিশন প্যানেলটি খুলে যাবে।

  4. প্রিন্সিপাল যোগ করুন -এ ক্লিক করুন।

  5. 'New principals' ফিল্ডে chat@system.gserviceaccount.com লিখুন।

  6. 'Select a role' মেনু থেকে 'Cloud Run' রোলটি নির্বাচন করুন।

    ক্লাউড রান ইনভোকার

  7. সংরক্ষণ করুন- এ ক্লিক করুন।

জিক্লাউড

gcloud functions add-invoker-policy-binding কমান্ডটি ব্যবহার করুন:

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

RECEIVING_FUNCTION জায়গায় আপনার চ্যাট অ্যাপের ফাংশনের নামটি বসান।

একটি আইডি টোকেন দিয়ে HTTP অনুরোধ প্রমাণীকরণ করুন

যদি চ্যাট অ্যাপ সংযোগ সেটিং -এর ‘অথেন্টিকেশন অডিয়েন্স’ ফিল্ডটি ‘HTTP এন্ডপয়েন্ট URL’- এ সেট করা থাকে, তাহলে অনুরোধের বিয়ারার অথরাইজেশন টোকেনটি একটি গুগল-স্বাক্ষরিত ওপেনআইডি কানেক্ট (OIDC) আইডি টোকেন হয়। email ফিল্ডটি chat@system.gserviceaccount.com এ সেট করা থাকে। ‘অথেন্টিকেশন অডিয়েন্স ’ ফিল্ডটি সেই URL-এ সেট করা থাকে, যা আপনি আপনার চ্যাট অ্যাপে অনুরোধ পাঠানোর জন্য গুগল চ্যাটকে কনফিগার করেছেন। উদাহরণস্বরূপ, যদি আপনার চ্যাট অ্যাপের কনফিগার করা এন্ডপয়েন্টটি https://example.com/app/ হয়, তাহলে আইডি টোকেনের ‘অথেন্টিকেশন অডিয়েন্স’ ফিল্ডটি হবে https://example.com/app/

This is the recommended authentication method if your HTTP endpoint isn't hosted on a service that supports IAM-based authentication (such as Cloud Run). Using this method, your HTTP service needs information about the URL of the endpoint where it's running, but doesn't need information about the Cloud project number.

নিম্নলিখিত নমুনাগুলিতে দেখানো হয়েছে কিভাবে গুগল OAuth ক্লায়েন্ট লাইব্রেরি ব্যবহার করে যাচাই করা যায় যে, বেয়ারার টোকেনটি গুগল চ্যাট দ্বারা ইস্যু করা হয়েছে এবং এটি আপনার অ্যাপের জন্যই উদ্দিষ্ট।

জাভা

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

নোড.জেএস

নোড/বেসিক-অ্যাপ/ইনডেক্স.জেএস
// 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 দিয়ে অনুরোধগুলি প্রমাণীকরণ করুন

যদি চ্যাট অ্যাপের সংযোগ সেটিং -এর ‘অথেন্টিকেশন অডিয়েন্স’ ফিল্ডটি Project Number -এ সেট করা থাকে, তাহলে অনুরোধের বিয়ারার অথরাইজেশন টোকেনটি হবে একটি সেলফ-সাইন্ড JSON ওয়েব টোকেন (JWT) , যা chat@system.gserviceaccount.com দ্বারা ইস্যু ও সাইন করা হয়েছে। audience ফিল্ডটি আপনার চ্যাট অ্যাপ তৈরি করতে ব্যবহৃত গুগল ক্লাউড প্রজেক্ট নম্বরে সেট করা থাকে। উদাহরণস্বরূপ, যদি আপনার চ্যাট অ্যাপের ক্লাউড প্রজেক্ট নম্বর 1234567890 হয়, তাহলে JWT-এর audience ফিল্ডটিও হবে 1234567890

এই প্রমাণীকরণ পদ্ধতিটি শুধুমাত্র তখনই সুপারিশ করা হয়, যদি আপনি HTTP এন্ডপয়েন্ট URL-এর পরিবর্তে অনুরোধ যাচাই করার জন্য ক্লাউড প্রজেক্ট নম্বর ব্যবহার করতে পছন্দ করেন। উদাহরণস্বরূপ, যদি আপনি একই ক্লাউড প্রজেক্ট নম্বর বজায় রেখে সময়ের সাথে সাথে এন্ডপয়েন্ট URL পরিবর্তন করতে চান, অথবা যদি আপনি একাধিক ক্লাউড প্রজেক্ট নম্বরের জন্য একই এন্ডপয়েন্ট ব্যবহার করতে চান এবং audience ফিল্ডটিকে ক্লাউড প্রজেক্ট নম্বরের একটি তালিকার সাথে তুলনা করতে চান।

নিম্নলিখিত নমুনাগুলিতে দেখানো হয়েছে কিভাবে গুগল OAuth ক্লায়েন্ট লাইব্রেরি ব্যবহার করে যাচাই করা যায় যে, বেয়ারার টোকেনটি গুগল চ্যাট দ্বারা ইস্যু করা হয়েছে এবং এটি আপনার প্রোজেক্টের জন্যই নির্দিষ্ট।

জাভা

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

নোড.জেএস

নোড/বেসিক-অ্যাপ/ইনডেক্স.জেএস
// 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;
}