محرک‌های مسدودسازی اصالت‌سنجی (نسل اول)

عملکردهای مسدودسازی به شما امکان می‌دهد کد سفارشی را اجرا کنید که نتیجه ثبت‌نام یا ورود کاربر به سیستم برنامه‌تان را تغییر می‌دهد. برای مثال، می‌توانید از اصالت‌سنجی کاربر درصورت عدم رعایت معیارهای خاص جلوگیری کنید، یا اطلاعات کاربر را قبل‌از برگرداندن آن به برنامه مشتری به‌روز کنید.

قبل از شروع

برای استفاده از توابع مسدودکننده، باید پروژه Firebase خود را به Firebase Authentication with Identity Platform ارتقا دهید. اگر قبلاً ارتقا نداده‌اید، ابتدا این کار را انجام دهید.

آشنایی با توابع مسدودسازی

می‌توانید توابع مسدودسازی را برای این رویدادها ثبت کنید:

  • beforeCreate: قبل‌از ذخیره شدن کاربر جدید در پایگاه داده Firebase Authentication و قبل‌از برگردانده شدن یک کد به برنامه کارخواه شما راه‌اندازی می‌شود.

  • beforeSignIn: پس‌از تأیید اعتبارنامه کاربر، اما قبل‌از اینکه Firebase Authentication یک شناسه ژتون به برنامه مشتری شما برگرداند، راه‌اندازی می‌شود. اگر برنامه شما از اصالت‌سنجی چندعاملی استفاده می‌کند، این تابع پس‌از اینکه کاربر عامل دوم خود را تأیید کرد، راه‌اندازی می‌شود. توجه داشته باشید که ایجاد کاربر جدید علاوه‌بر beforeCreate، beforeSignIn را نیز راه‌اندازی می‌کند.

  • beforeEmail (فقط Node.js): قبل‌از ارسال ایمیل (برای مثال،
    ایمیل ورود به سیستم یا بازنشانی گذرواژه) به کاربر راه‌اندازی می‌شود.

  • beforeSms (فقط Node.js): قبل‌از ارسال پیامک به کاربر، برای مواردی مانند اصالت‌سنجی چندعاملی، راه‌اندازی می‌شود.

هنگام استفاده از توابع مسدودسازی، موارد زیر را درنظر داشته باشید:

  • تابع شما باید ظرف ۷ ثانیه پاسخ دهد. پس‌از ۷ ثانیه، Firebase Authentication خطایی برمی‌گرداند و عملیات کارخواه ناموفق می‌شود.

  • کدهای پاسخ HTTP به‌غیراز 200 به برنامه‌های مشتری شما ارسال می‌شود. مطمئن شوید کد کارخواه شما هرگونه خطایی را که تابع شما می‌تواند برگرداند مدیریت می‌کند.

  • توابع برای همه کاربران پروژه شما اعمال می‌شود، ازجمله هر کاربری که در یک مستأجر قرار دارد. Firebase Authentication اطلاعاتی درباره کاربران به تابع شما ارائه می‌دهد، ازجمله هر مستأجری که به آن تعلق دارند، تا بتوانید به‌طور مقتضی پاسخ دهید.

  • پیوند دادن ارائه‌دهنده هویت دیگری به حساب، هرگونه تابع beforeSignIn ثبت‌شده را دوباره راه‌اندازی می‌کند.

  • اصالت‌سنجی ناشناس و سفارشی باعث راه‌اندازی عملکردهای مسدودسازی نمی‌شود.

استقرار تابع مسدودسازی

برای درج کد سفارشی‌تان در جریان‌های اصالت‌سنجی کاربر، توابع مسدودسازی را مستقر کنید. پس‌از اینکه عملکردهای مسدودسازی شما مستقر شد، کد سفارشی شما باید باموفقیت تکمیل شود تا اصالت‌سنجی و ایجاد کاربر موفقیت‌آمیز باشد.

تابع مسدودسازی را به همان روشی که هر تابع دیگری را مستقر می‌کنید، مستقر می‌کنید. (برای جزئیات، به صفحه Cloud Functions شروع به کار مراجعه کنید). به‌طور خلاصه:

  1. تابعی بنویسید که رویداد هدف را مدیریت کند.

    برای مثال، برای شروع می‌توانید تابع بدون عملیاتی مثل تابع زیر را به index.js اضافه کنید:

    const functions = require('firebase-functions/v1');
    
    exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
      // TODO
    });
    
    The above example has omitted the implementation of custom auth logic. See
    the following sections to learn how to implement your blocking functions and
    [Common scenarios](#common-scenarios) for specific examples.
    
  1. توابع خود را بااستفاده از Firebase CLI مستقر کنید:

    firebase deploy --only functions
    

    هر بار که توابع را به‌روز می‌کنید، باید آن‌ها را دوباره مستقر کنید.

درحال دریافت اطلاعات کاربر و بافت

رویدادهای beforeSignIn و beforeCreate اشیاء User و EventContext را ارائه می‌دهند که حاوی اطلاعاتی درباره ورود کاربر به سیستم است. از این مقادیر در کدتان استفاده کنید تا مشخص شود آیا عملیات می‌تواند ادامه یابد یا نه.

برای مشاهده فهرست ویژگی‌های دردسترس در شیء User، مرجع میانای برنامه‌سازی کاربردی UserRecord را ببینید.

شیء EventContext حاوی ویژگی‌های زیر است:

نام شرح مثال
locale منطقه زبانی برنامه. می‌توانید بااستفاده از کیت توسعه نرم‌افزار کارخواه یا با ارسال سرصفحه منطقه زبانی در REST API، منطقه زبانی را تنظیم کنید. fr یا sv-SE
ipAddress نشانی IP دستگاهی که کاربر نهایی از آن ثبت‌نام می‌کند یا به سیستم وارد می‌شود. 114.14.200.1
userAgent نماینده کاربر که عملکرد مسدودسازی را راه‌اندازی می‌کند. Mozilla/5.0 (X11; Linux x86_64)
eventId شناسه یکتای رویداد. rWsyPtolplG2TBFoOkkgyg
eventType نوع رویداد. این گزینه اطلاعاتی درباره نام رویداد، مثل beforeSignIn یا beforeCreate، و روش ورود به سیستم مرتبط مورداستفاده، مثل Google یا ایمیل/گذرواژه، ارائه می‌دهد. providers/cloud.auth/eventTypes/user.beforeSignIn:password
authType همیشه USER. USER
resource پروژه یا مستأجر Firebase Authentication. projects/project-id/tenants/tenant-id
timestamp زمانی که رویداد راه‌اندازی شد، قالب‌بندی‌شده به‌عنوان رشته RFC 3339. Tue, 23 Jul 2019 21:10:57 GMT
additionalUserInfo شیء حاوی اطلاعاتی درباره کاربر. AdditionalUserInfo
credential شیئی حاوی اطلاعات درباره اطلاعات کاربری کاربر. AuthCredential

مسدود کردن ثبت‌نام یا ورود به سیستم

برای مسدود کردن تلاش برای ثبت‌نام یا ورود به سیستم، یک HttpsError در تابع خود ایجاد کنید. برای مثال:

Node.js

throw new functions.auth.HttpsError('permission-denied');

جدول زیر خطاهایی را که می‌توانید مطرح کنید، به‌همراه پیام خطای پیش‌فرض آن‌ها، فهرست می‌کند:

نام کد پیام
invalid-argument 400 متغیر مستقلی که کارخواه تعیین کرده است نامعتبر است.
failed-precondition 400 در حالت کنونی سیستم، امکان اجرای درخواست وجود ندارد.
out-of-range 400 گستره‌ای که کارخواه تعیین کرده است نامعتبر است.
unauthenticated 401 کد OAuth وجود ندارد، نامعتبر است، یا منقضی شده است.
permission-denied 403 کارخواه مجوز کافی ندارد.
not-found 404 منبع مشخص‌شده پیدا نشد.
aborted 409 تداخل هم‌زمانی، مانند تداخل خواندن-اصلاح-نوشتن.
already-exists 409 منبعی که کارخواه قصد ایجادش را داشت از قبل موجود است.
resource-exhausted 429 یا از سهمیه منبع خارج شدید یا از حداکثر مجاز فراتر رفتید.
cancelled 499 کارخواه درخواست را لغو کرد.
data-loss 500 از بین‌رفتن داده‌ها یا خرابی داده‌ها به‌طور غیرقابل بازیابی.
unknown 500 خطای سرور نامشخص.
internal 500 خطای سرور داخلی.
not-implemented 501 سرور روش «میانای برنامه‌سازی کاربردی» را پیاده‌سازی نکرده است.
unavailable 503 سرویس دردسترس نیست.
deadline-exceeded 504 از مهلت درخواست فراتر رفتید.

همچنین می‌توانید پیام خطای سفارشی مشخص کنید:

Node.js

throw new functions.auth.HttpsError('permission-denied', 'Unauthorized request origin!');

مثال زیر نشان می‌دهد که چگونه کاربرانی را که در دامنه خاصی نیستند از ثبت‌نام در برنامه‌تان مسدود کنید:

Node.js

exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
  // (If the user is authenticating within a tenant context, the tenant ID can be determined from
  // user.tenantId or from context.resource, e.g. 'projects/project-id/tenant/tenant-id-1')

  // Only users of a specific domain can sign up.
  if (user.email.indexOf('@acme.com') === -1) {
    throw new functions.auth.HttpsError('invalid-argument', `Unauthorized email "${user.email}"`);
  }
});

صرف‌نظر از اینکه از پیام پیش‌فرض یا سفارشی استفاده می‌کنید، Cloud Functions خطا را بسته‌بندی می‌کند و آن را به‌عنوان خطای داخلی به کارخواه برمی‌گرداند. برای مثال:

throw new functions.auth.HttpsError('invalid-argument', `Unauthorized email user@evil.com}`);

برنامه شما باید خطا را شناسایی کند و به‌طور مناسب آن را مدیریت کند. برای مثال:

جاوا اسکریپت

// Blocking functions can also be triggered in a multi-tenant context before user creation.
// firebase.auth().tenantId = 'tenant-id-1';
firebase.auth().createUserWithEmailAndPassword('johndoe@example.com', 'password')
  .then((result) => {
    result.user.getIdTokenResult()
  })
  .then((idTokenResult) => {
    console.log(idTokenResult.claim.admin);
  })
  .catch((error) => {
    if (error.code !== 'auth/internal-error' && error.message.indexOf('Cloud Function') !== -1) {
      // Display error.
    } else {
      // Registration succeeds.
    }
  });

درحال اصلاح کاربر

به‌جای مسدود کردن تلاش برای ثبت‌نام یا ورود به سیستم، می‌توانید اجازه دهید عملیات ادامه یابد، اما شیء User را که در پایگاه داده Firebase Authentication ذخیره شده است و به کارخواه برگردانده می‌شود اصلاح کنید.

برای اصلاح کاربر، شیئی را از گرداننده رویداد خود برگردانید که حاوی فیلدهای اصلاح باشد. می‌توانید فیلدهای زیر را اصلاح کنید:

  • displayName
  • disabled
  • emailVerified
  • photoUrl
  • customClaims
  • sessionClaims (فقط beforeSignIn)

به‌استثنای sessionClaims، همه فیلدهای اصلاح‌شده در پایگاه داده Firebase Authentication ذخیره می‌شوند، یعنی در کد پاسخ گنجانده می‌شوند و بین جلسه‌های کاربر باقی می‌مانند.

مثال زیر نحوه تنظیم نام نمایشی پیش‌فرض را نشان می‌دهد:

Node.js

exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
  return {
    // If no display name is provided, set it to "Guest".
    displayName: user.displayName || 'Guest';
  };
});

اگر یک گرداننده رویداد را برای هر دو beforeCreate و beforeSignIn ثبت کنید، توجه داشته باشید که beforeSignIn پس‌از beforeCreate اجرا می‌شود. فیلدهای کاربر به‌روزشده در beforeCreate در beforeSignIn قابل‌مشاهده است. اگر فیلدی غیراز sessionClaims را در هر دو گرداننده رویداد تنظیم کنید، مقدار تنظیم‌شده در beforeSignIn روی مقدار تنظیم‌شده در beforeCreate بازنویسی می‌شود. فقط برای sessionClaims، آن‌ها به ادعاهای توکن جلسه فعلی منتشر می‌شوند، اما در پایگاه داده ذخیره یا نگهداری نمی‌شوند.

برای مثال، اگر هرگونه sessionClaims تنظیم شده باشد، beforeSignIn آن‌ها را با هرگونه ادعای beforeCreate برمی‌گرداند و آن‌ها ادغام خواهند شد. وقتی ادغام می‌شوند، اگر کلید sessionClaims با کلیدی در customClaims مطابقت داشته باشد، customClaims منطبق در ادعاهای کد با کلید sessionClaims رونویسی خواهد شد. بااین‌حال، کلید customClaims رونویسی‌شده همچنان در پایگاه داده برای درخواست‌های آتی باقی خواهد ماند.

اعتبارنامه‌ها و داده‌های OAuth پشتیبانی‌شده

می‌توانید اطلاعات کاربری و داده‌های OAuth را از ارائه‌دهندگان هویت مختلف به توابع مسدودکننده ارسال کنید. جدول زیر نشان می‌دهد چه اطلاعات کاربری و داده‌هایی برای هر ارائه‌دهنده هویت پشتیبانی می‌شود:

ارائه‌دهنده هویت کد شناسه کد دسترسی زمان انقضا رمز کد ژتون بازآوری ادعاهای ورود به سیستم
Google بله بله بله نه بله نه
فیس‌بوک نه بله بله نه نه نه
Twitter نه بله نه بله نه نه
GitHub نه بله نه نه نه نه
Microsoft بله بله بله نه بله نه
LinkedIn نه بله بله نه نه نه
Yahoo بله بله بله نه بله نه
Apple بله بله بله نه بله نه
SAML نه نه نه نه نه بله
OIDC بله بله بله نه بله بله

ژتون‌های بازآوری

برای استفاده از ژتون بازآوری در تابع مسدودسازی، ابتدا باید چارگوش انتخاب را در صفحه توابع مسدودسازی در کنسول Firebase انتخاب کنید (به برگه امنیت > اصالت‌سنجی > تنظیمات بروید).

هنگام ورود به سیستم به‌طور مستقیم با اعتبارنامه OAuth، مانند ژتون شناسه یا ژتون دسترسی، هیچ ارائه‌دهنده هویتی ژتون بازآوری را برنمی‌گرداند. در این شرایط، همان اعتبارنامه OAuth سمت کارخواه به تابع مسدودکننده منتقل خواهد شد.

بخش‌های زیر هریک از انواع ارائه‌دهنده هویت و اطلاعات کاربری و داده‌های پشتیبانی‌شده آن‌ها را شرح می‌دهد.

ارائه‌دهندگان OIDC عمومی

وقتی کاربری با ارائه‌دهنده OIDC عمومی به سیستم وارد می‌شود، اعتبارنامه‌های زیر منتقل خواهد شد:

  • شناسه ژتون: اگر جریان id_token انتخاب شده باشد ارائه می‌شود.
  • کد دسترسی: درصورت انتخاب جریان کد ارائه می‌شود. توجه داشته باشید که جریان کد درحال‌حاضر فقط ازطریق REST API پشتیبانی می‌شود.
  • ژتون بازآوری: درصورت انتخاب offline_access گستره ارائه می‌شود.

مثال:

const provider = new firebase.auth.OAuthProvider('oidc.my-provider');
provider.addScope('offline_access');
firebase.auth().signInWithPopup(provider);

Google

وقتی کاربری با Google به سیستم وارد می‌شود، اطلاعات کاربری زیر منتقل خواهد شد:

  • نشان شناسه
  • کد دسترسی
  • ژتون بازآوری: فقط درصورتی ارائه می‌شود که پارامترهای سفارشی زیر درخواست شده باشد:
    • access_type=offline
    • prompt=consent، اگر کاربر قبلاً رضایت داده باشد و دامنه جدیدی درخواست نشده باشد

مثال:

const provider = new firebase.auth.GoogleAuthProvider();
provider.setCustomParameters({
  'access_type': 'offline',
  'prompt': 'consent'
});
firebase.auth().signInWithPopup(provider);

درباره ژتون‌های بازآوری Google بیشتر بدانید.

فیس‌بوک

وقتی کاربری با Facebook به سیستم وارد می‌شود، اطلاعات کاربری زیر ارسال می‌شود:

  • کد دسترسی: کد دسترسی‌ای برگردانده می‌شود که می‌توان آن را با کد دسترسی دیگری مبادله کرد. درباره انواع مختلف کدهای دسترسی پشتیبانی‌شده توسط Facebook و نحوه مبادله آن‌ها با کدهای با طول عمر بالا بیشتر بدانید.

GitHub

وقتی کاربری با GitHub به سیستم وارد می‌شود، اعتبارنامه زیر ارسال خواهد شد:

  • کد دسترسی: منقضی نمی‌شود مگراینکه لغو شود.

Microsoft

وقتی کاربری با Microsoft به سیستم وارد می‌شود، اعتبارنامه‌های زیر ارسال می‌شود:

  • نشان شناسه
  • کد دسترسی
  • ژتون بازآوری: اگر offline_access دامنه انتخاب شده باشد، به تابع مسدودسازی ارسال می‌شود.

مثال:

const provider = new firebase.auth.OAuthProvider('microsoft.com');
provider.addScope('offline_access');
firebase.auth().signInWithPopup(provider);

Yahoo

وقتی کاربری با Yahoo به سیستم وارد می‌شود، اطلاعات اعتباری زیر بدون هیچ‌گونه پارامتر یا دامنه سفارشی ارسال خواهد شد:

  • نشان شناسه
  • کد دسترسی
  • ژتون بازآوری

LinkedIn

وقتی کاربری با LinkedIn به سیستم وارد می‌شود، اطلاعات کاربری زیر ارسال خواهد شد:

  • کد دسترسی

Apple

وقتی کاربری با Apple به سیستم وارد می‌شود، اطلاعات اعتباری زیر بدون هیچ‌گونه پارامتر یا دامنه سفارشی ارسال خواهد شد:

  • نشان شناسه
  • کد دسترسی
  • ژتون بازآوری

سناریوهای رایج

نمونه‌های زیر برخی‌از موارد استفاده رایج برای توابع مسدودسازی را نشان می‌دهند:

فقط ثبت‌نام از دامنه‌ای خاص مجاز است

مثال زیر نشان می‌دهد چگونه می‌توانید از ثبت‌نام کاربرانی که عضو دامنه example.com نیستند در برنامه‌تان جلوگیری کنید:

Node.js

exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
  if (!user.email || user.email.indexOf('@example.com') === -1) {
    throw new functions.auth.HttpsError(
      'invalid-argument', `Unauthorized email "${user.email}"`);
  }
});

مسدود کردن ثبت‌نام کاربران با ایمیل‌های تأییدنشده

مثال زیر نشان می‌دهد چگونه از ثبت‌نام کاربران با ایمیل‌های تأییدنشده در برنامه‌تان جلوگیری کنید:

Node.js

exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
  if (user.email && !user.emailVerified) {
    throw new functions.auth.HttpsError(
      'invalid-argument', `Unverified email "${user.email}"`);
  }
});

الزامی کردن درستی‌سنجی ایمیل هنگام ثبت‌نام

مثال زیر نشان می‌دهد که چگونه می‌توان کاربر را ملزم کرد که ایمیل خود را پس‌از ثبت‌نام درستی‌سنجی کند:

Node.js

exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
  const locale = context.locale;
  if (user.email && !user.emailVerified) {
    // Send custom email verification on sign-up.
    return admin.auth().generateEmailVerificationLink(user.email).then((link) => {
      return sendCustomVerificationEmail(user.email, link, locale);
    });
  }
});

exports.beforeSignIn = functions.auth.user().beforeSignIn((user, context) => {
 if (user.email && !user.emailVerified) {
   throw new functions.auth.HttpsError(
     'invalid-argument', `"${user.email}" needs to be verified before access is granted.`);
  }
});

درنظر گرفتن برخی ایمیل‌های ارائه‌دهنده هویت به‌عنوان تأییدشده

مثال زیر نشان می‌دهد که چگونه ایمیل‌های کاربر از ارائه‌دهندگان هویت خاص را به‌عنوان تأییدشده درنظر بگیرید:

Node.js

exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
  if (user.email && !user.emailVerified && context.eventType.indexOf(':facebook.com') !== -1) {
    return {
      emailVerified: true,
    };
  }
});

مسدود کردن ورود به سیستم از نشانی‌های IP خاص

مثال زیر نحوه مسدود کردن ورود به سیستم از محدوده‌های نشانی IP خاص را نشان می‌دهد:

Node.js

exports.beforeSignIn = functions.auth.user().beforeSignIn((user, context) => {
  if (isSuspiciousIpAddress(context.ipAddress)) {
    throw new functions.auth.HttpsError(
      'permission-denied', 'Unauthorized access!');
  }
});

تنظیم ادعاهای سفارشی و جلسه

مثال زیر نشان می‌دهد که چگونه ادعاهای سفارشی و جلسه را تنظیم کنید:

Node.js

exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
  if (context.credential &&
      context.credential.providerId === 'saml.my-provider-id') {
    return {
      // Employee ID does not change so save in persistent claims (stored in
      // Auth DB).
      customClaims: {
        eid: context.credential.claims.employeeid,
      },
      // Copy role and groups to token claims. These will not be persisted.
      sessionClaims: {
        role: context.credential.claims.role,
        groups: context.credential.claims.groups,
      }
    }
  }
});

ردیابی نشانی‌های IP برای پایش فعالیت‌های مشکوک

با ردیابی نشانی IP که کاربر از آن به سیستم وارد می‌شود و مقایسه آن با نشانی IP در درخواست‌های بعدی، می‌توانید از سرقت کد جلوگیری کنید. اگر درخواست مشکوک به‌نظر می‌رسد (برای مثال، IPها از مناطق جغرافیایی مختلفی هستند)، می‌توانید از کاربر بخواهید دوباره به سیستم وارد شود.

  1. از ادعاهای جلسه برای ردیابی نشانی IP که کاربر با آن به سیستم وارد می‌شود استفاده کنید:

    Node.js

    exports.beforeSignIn = functions.auth.user().beforeSignIn((user, context) => {
      return {
        sessionClaims: {
          signInIpAddress: context.ipAddress,
        },
      };
    });
    
  2. وقتی کاربری تلاش می‌کند به منابعی دسترسی پیدا کند که به اصالت‌سنجی با Firebase Authentication نیاز دارند، نشانی IP موجود در درخواست را با IP استفاده‌شده برای ورود به سیستم مقایسه کنید:

    Node.js

    app.post('/getRestrictedData', (req, res) => {
      // Get the ID token passed.
      const idToken = req.body.idToken;
      // Verify the ID token, check if revoked and decode its payload.
      admin.auth().verifyIdToken(idToken, true).then((claims) => {
        // Get request IP address
        const requestIpAddress = req.connection.remoteAddress;
        // Get sign-in IP address.
        const signInIpAddress = claims.signInIpAddress;
        // Check if the request IP address origin is suspicious relative to
        // the session IP addresses. The current request timestamp and the
        // auth_time of the ID token can provide additional signals of abuse,
        // especially if the IP address suddenly changed. If there was a sudden
        // geographical change in a short period of time, then it will give
        // stronger signals of possible abuse.
        if (!isSuspiciousIpAddressChange(signInIpAddress, requestIpAddress)) {
          // Suspicious IP address change. Require re-authentication.
          // You can also revoke all user sessions by calling:
          // admin.auth().revokeRefreshTokens(claims.sub).
          res.status(401).send({error: 'Unauthorized access. Please login again!'});
        } else {
          // Access is valid. Try to return data.
          getData(claims).then(data => {
            res.end(JSON.stringify(data);
          }, error => {
            res.status(500).send({ error: 'Server error!' })
          });
        }
      });
    });
    

بررسی عکس‌های کاربر

مثال زیر نحوه پاک‌سازی عکس‌های نمایه کاربران را نشان می‌دهد:

Node.js

exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
  if (user.photoURL) {
    return isPhotoAppropriate(user.photoURL)
      .then((status) => {
        if (!status) {
          // Sanitize inappropriate photos by replacing them with guest photos.
          // Users could also be blocked from sign-up, disabled, etc.
          return {
            photoUrl: PLACEHOLDER_GUEST_PHOTO_URL,
          };
        }
      });
});

برای کسب اطلاعات بیشتر درباره نحوه شناسایی و پاک‌سازی تصاویر، به اسناد Cloud Vision مراجعه کنید.

دسترسی به اعتبارنامه‌های OAuth ارائه‌دهنده هویت کاربر

مثال زیر نشان می‌دهد که چگونه یک ژتون بازآوری برای کاربری که با Google وارد سیستم شده است دریافت کنید و از آن برای فراخوانی Google Calendar APIs استفاده کنید. ژتون بازآوری برای دسترسی آفلاین ذخیره می‌شود.

Node.js

const {OAuth2Client} = require('google-auth-library');
const {google} = require('googleapis');
// ...
// Initialize Google OAuth client.
const keys = require('./oauth2.keys.json');
const oAuth2Client = new OAuth2Client(
  keys.web.client_id,
  keys.web.client_secret
);

exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
  if (context.credential &&
      context.credential.providerId === 'google.com') {
    // Store the refresh token for later offline use.
    // These will only be returned if refresh tokens credentials are included
    // (enabled by Cloud console).
    return saveUserRefreshToken(
        user.uid,
        context.credential.refreshToken,
        'google.com'
      )
      .then(() => {
        // Blocking the function is not required. The function can resolve while
        // this operation continues to run in the background.
        return new Promise((resolve, reject) => {
          // For this operation to succeed, the appropriate OAuth scope should be requested
          // on sign in with Google, client-side. In this case:
          // https://www.googleapis.com/auth/calendar
          // You can check granted_scopes from within:
          // context.additionalUserInfo.profile.granted_scopes (space joined list of scopes).

          // Set access token/refresh token.
          oAuth2Client.setCredentials({
            access_token: context.credential.accessToken,
            refresh_token: context.credential.refreshToken,
          });
          const calendar = google.calendar('v3');
          // Setup Onboarding event on user's calendar.
          const event = {/** ... */};
          calendar.events.insert({
            auth: oauth2client,
            calendarId: 'primary',
            resource: event,
          }, (err, event) => {
            // Do not fail. This is a best effort approach.
            resolve();
          });
      });
    })
  }
});

لغو کردن حکم reCAPTCHA Enterprise برای عملیات کاربر

مثال زیر نحوه لغو کردن حکم reCAPTCHA Enterprise را برای جریان‌های کاربر پشتیبانی‌شده نشان می‌دهد.

برای کسب اطلاعات بیشتر درباره ادغام reCAPTCHA Enterprise با «اصالت‌سنجی Firebase»، به فعال کردن reCAPTCHA Enterprise مراجعه کنید.

از توابع مسدودسازی می‌توان برای مجاز کردن یا مسدود کردن جریان‌ها براساس عوامل سفارشی استفاده کرد و درنتیجه نتیجه ارائه‌شده توسط reCAPTCHA Enterprise را لغو کرد.

Node.js

const functions = require("firebase-functions/v1");
exports.beforesmsv1 = functions.auth.user().beforeSms((context) => {
 if (
   context.smsType === "SIGN_IN_OR_SIGN_UP" &&
   context.additionalUserInfo.phoneNumber.includes('+91')
 ) {
   return {
     recaptchaActionOverride: "ALLOW",
   };
 }

 // Allow users to sign in with recaptcha score greater than 0.5
 if (event.additionalUserInfo.recaptchaScore > 0.5) {
   return {
     recaptchaActionOverride: 'ALLOW',
   };
 }

 // Block all others.
 return  {
   recaptchaActionOverride: 'BLOCK',
 }
});