درخواست‌های Google Chat را تأیید کنید

برای برنامه‌های گوگل چت که بر روی نقاط پایانی HTTP ساخته شده‌اند، این بخش نحوه تأیید اینکه درخواست‌های ارسالی به نقطه پایانی شما از Chat می‌آیند را توضیح می‌دهد.

برای ارسال رویدادهای تعاملی به نقطه پایانی برنامه چت شما، گوگل درخواست‌هایی را به سرویس شما ارسال می‌کند. برای تأیید اینکه درخواست از گوگل می‌آید، چت یک توکن حامل را در هدر Authorization هر درخواست HTTPS به نقطه پایانی شما قرار می‌دهد. به عنوان مثال:

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

رشته AbCdEf123456 در مثال قبلی، توکن مجوز حامل است. این یک توکن رمزنگاری است که توسط گوگل تولید شده است. نوع توکن حامل و مقدار فیلد audience به نوع مخاطب احراز هویتی که هنگام پیکربندی برنامه چت انتخاب کرده‌اید، بستگی دارد.

اگر برنامه چت خود را با استفاده از توابع Cloud Run پیاده‌سازی کرده‌اید، Cloud IAM تأیید توکن را به طور خودکار انجام می‌دهد. شما باید حساب سرویس Google Chat را به عنوان یک فراخوانی‌کننده مجاز اضافه کنید. اگر برنامه شما سرور HTTP مخصوص به خود را پیاده‌سازی می‌کند، می‌توانید توکن حامل خود را با استفاده از یک کتابخانه کلاینت Google API متن‌باز تأیید کنید:

اگر توکن برای برنامه چت تأیید نشود، سرویس شما باید با کد پاسخ HTTPS 401 (Unauthorized) به درخواست پاسخ دهد.

درخواست‌ها را با استفاده از توابع Cloud Run تأیید کنید

اگر منطق تابع شما با استفاده از توابع Cloud Run پیاده‌سازی شده است، باید در قسمت Authentication Audience از تنظیمات اتصال برنامه چت، HTTP endpoint URL را انتخاب کنید و مطمئن شوید که HTTP endpoint URL در پیکربندی با URL تابع Cloud Run مطابقت دارد.

سپس، باید با استفاده از مراحل زیر، حساب سرویس چت گوگل chat@system.gserviceaccount.com را به عنوان یک فراخوانی‌کننده مجاز کنید:

کنسول

پس از استقرار عملکرد یا سرویس خود در Google Cloud:

  1. در کنسول گوگل کلود، به صفحه Cloud Run بروید:

    به Cloud Run بروید

  2. در لیست سرویس‌های Cloud Run، روی کادر انتخاب کنار تابع دریافت کلیک کنید. (روی خود تابع کلیک نکنید.)

  3. روی مجوزها در بالای صفحه کلیک کنید. پنل مجوزها باز می‌شود.

  4. روی افزودن مدیر اصلی کلیک کنید.

  5. در فیلد «مدیران جدید» ، chat@system.gserviceaccount.com را وارد کنید.

  6. از منوی انتخاب نقش ، نقش Cloud Run را انتخاب کنید

    اجرای ابری Invoker .

  7. روی ذخیره کلیک کنید.

جی‌کلاود

از دستور gcloud functions add-invoker-policy-binding استفاده کنید:

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

به جای RECEIVING_FUNCTION نام تابع برنامه چت خود را قرار دهید.

درخواست‌های HTTP را با یک شناسه توکن (ID Token) تأیید اعتبار کنید

اگر فیلد مخاطب احراز هویت در تنظیمات اتصال برنامه چت روی HTTP endpoint URL تنظیم شده باشد، توکن مجوز حامل در درخواست، یک توکن شناسه OpenID Connect (OIDC) امضا شده توسط گوگل است. فیلد email روی chat@system.gserviceaccount.com تنظیم شده است. فیلد مخاطب احراز هویت روی URL ای تنظیم شده است که شما Google Chat را برای ارسال درخواست‌ها به برنامه چت خود پیکربندی کرده‌اید. به عنوان مثال، اگر نقطه پایانی پیکربندی شده برنامه چت شما https://example.com/app/ باشد، فیلد مخاطب احراز هویت در توکن شناسه https://example.com/app/ خواهد بود.

این روش احراز هویت توصیه شده است اگر نقطه پایانی HTTP شما روی سرویسی که از احراز هویت مبتنی بر IAM پشتیبانی می‌کند (مانند Cloud Run) میزبانی نمی‌شود. با استفاده از این روش، سرویس HTTP شما به اطلاعاتی در مورد URL نقطه پایانی که در آن اجرا می‌شود نیاز دارد، اما به اطلاعاتی در مورد شماره پروژه Cloud نیازی ندارد.

نمونه‌های زیر نشان می‌دهند که چگونه می‌توان با استفاده از کتابخانه کلاینت Google OAuth، تأیید کرد که توکن حامل توسط Google Chat صادر شده و برنامه شما را هدف قرار داده است.

جاوا

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

پایتون

پایتون/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

نود جی اس

گره/برنامه پایه/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 تأیید اعتبار کنید

اگر فیلد «مخاطب احراز هویت» در تنظیمات اتصال برنامه چت روی « Project Number » تنظیم شده باشد، توکن مجوز حامل در درخواست، یک توکن وب JSON (JWT) خودامضا شده است که توسط chat@system.gserviceaccount.com صادر و امضا شده است. فیلد audience روی شماره پروژه Google Cloud که برای ساخت برنامه چت خود استفاده کرده‌اید تنظیم شده است. برای مثال، اگر شماره پروژه Cloud برنامه چت شما 1234567890 باشد، فیلد audience در JWT 1234567890 خواهد بود.

این روش احراز هویت فقط در صورتی توصیه می‌شود که ترجیح می‌دهید از شماره پروژه ابری برای تأیید درخواست‌ها به جای آدرس اینترنتی نقطه پایانی HTTP استفاده کنید. به عنوان مثال، اگر می‌خواهید آدرس اینترنتی نقطه پایانی را به مرور زمان تغییر دهید در حالی که شماره پروژه ابری یکسانی را حفظ کنید، یا اگر می‌خواهید از یک نقطه پایانی برای چندین شماره پروژه ابری استفاده کنید و می‌خواهید فیلد audience را با لیستی از شماره پروژه‌های ابری مقایسه کنید.

نمونه‌های زیر نشان می‌دهند که چگونه با استفاده از کتابخانه کلاینت Google OAuth، تأیید کنید که توکن حامل توسط Google Chat صادر شده و برای پروژه شما در نظر گرفته شده است.

جاوا

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

پایتون

پایتون/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

نود جی اس

گره/برنامه پایه/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;
}