توسيع نطاق مصادقة Firebase باستخدام وظائف الحظر


تتيح لك دوال الحظر تنفيذ رموز مخصَّصة تعمل على تعديل نتيجة تسجيل المستخدم في تطبيقك أو تسجيل الدخول إليه على سبيل المثال، يمكنك منع مستخدم من المصادقة إذا كانت لا تستوفي معايير معينة، أو يمكنها تحديث صفحة المعلومات قبل إعادتها إلى تطبيق العميل.

قبل البدء

لاستخدام وظائف الحظر، يجب ترقية مشروع Firebase إلى مصادقة Firebase باستخدام النظام الأساسي للهوية. إذا لم تكن قد أجريت الترقية من قبل، عليك إجراء ذلك أولاً.

فهم دوال الحظر

ويمكنك تسجيل وظائف الحظر لحدثَين:

  • beforeCreate: إجراءات يتم تشغيلها قبل حفظ مستخدم جديد في بقاعدة بيانات مصادقة Firebase وقبل إرجاع رمز إلى تطبيق العميل.

  • beforeSignIn: يتم تشغيله بعد إثبات صحة بيانات اعتماد المستخدم، ولكن قبل أن تُرجع مصادقة Firebase رمزًا مميزًا للمعرف إلى تطبيق العميل. في حال حذف أن تطبيقك يستخدم مصادقة متعددة العوامل، عندما يتحقق المستخدم من عامله الثاني. لاحظ أن إنشاء مخطط جديد يؤدي المستخدم أيضًا إلى تشغيل beforeSignIn، بالإضافة إلى beforeCreate.

يجب أخذ النقاط التالية في الاعتبار عند استخدام دوال الحظر:

  • يجب أن تستجيب الدالة في غضون 7 ثوانٍ. بعد 7 ثوانٍ، تعرض مصادقة Firebase خطأً، وإخفاق عملية العميل.

  • يتم تمرير رموز استجابة HTTP بخلاف 200 إلى تطبيقات العميل. التأكد من يتعامل رمز العميل مع أي أخطاء يمكن أن تعرضها الدالة.

  • تنطبق الدوال على جميع المستخدمين في مشروعك، بما في ذلك أي مستخدمين مضمنة في المستأجر. توفر مصادقة Firebase معلومات عن المستخدمين لوظيفتك، بما في ذلك أي مستأجرين ينتمون إليه بحيث يمكنك الردّ وفقًا لذلك.

  • يؤدي ربط موفِّر هوية آخر بحساب إلى إعادة تشغيل أي موفّر هوية مسجَّل beforeSignIn.

  • لا تؤدي المصادقة المجهولة والمخصَّصة إلى تشغيل وظائف الحظر.

تفعيل دالة حظر

لإدراج الرمز المخصّص في مسارات مصادقة المستخدمين، فعِّل ميزة الحظر الأخرى. بعد نشر دوال الحظر، يجب أن يكون الرمز المخصّص سيكتمل بنجاح للمصادقة وإنشاء المستخدم.

تنشر دالة حظر بالطريقة نفسها التي تنشر بها أي دالة. (يُرجى الاطّلاع على صفحة بدء استخدام دوال السحابة الإلكترونية للحصول على التفاصيل). وباختصار:

  1. اكتب دوال السحابة الإلكترونية التي تتعامل مع حدث beforeCreate، حدث واحد (beforeSignIn) أو كليهما.

    على سبيل المثال، للبدء، يمكنك إضافة دوال No-op التالية إلى index.js:

    const functions = require('firebase-functions');
    
    exports.beforeCreate = functions.auth.user().beforeCreate((user, context) => {
      // TODO
    });
    
    exports.beforeSignIn = functions.auth.user().beforeSignIn((user, context) => {
      // TODO
    });
    

    حذّرت الأمثلة أعلاه تنفيذ منطق المصادقة المخصّص. عرض للاطلاع على كيفية تنفيذ دوال الحظر السيناريوهات الشائعة لأمثلة محدّدة.

  2. انشر الدوال باستخدام واجهة سطر الأوامر لمنصّة Firebase:

    firebase deploy --only functions
    

    يجب إعادة نشر الدوال في كل مرة تقوم فيها بتحديثها.

الحصول على معلومات المستخدم والسياق

يعرض الحدثان beforeSignIn وbeforeCreate User وEventContext. الكائنات التي تحتوي على معلومات حول تسجيل دخول المستخدم. استخدِم هذه القيم. في التعليمات البرمجية لتحديد ما إذا كان يجب السماح بمتابعة العملية.

للحصول على قائمة بالسمات المتوفّرة في العنصر User، يمكنك الاطّلاع على UserRecord مرجع واجهة برمجة التطبيقات.

يحتوي الكائن EventContext على السمات التالية:

الاسم الوصف مثال
locale لغة التطبيق. يمكنك تعيين اللغة باستخدام العميل SDK، أو عن طريق تمرير عنوان اللغة في واجهة برمجة تطبيقات REST. 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 أو المستأجر 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 الخطأ وتعرضه للعميل في صورة خطأ داخلي. على سبيل المثال:

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

من المفترض أن يرصد تطبيقك الخطأ، وأن يتعامل معه وفقًا لذلك. على سبيل المثال:

JavaScript

// 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 وتم إرجاعها إلى العميل.

لتعديل مستخدم، يمكنك إرجاع كائن من معالج الأحداث يحتوي على الحقول المطلوب تعديلها. يمكنك تعديل الحقول التالية:

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

يتم حفظ جميع الحقول المعدَّلة باستثناء sessionClaims في قاعدة بيانات مصادقة Firebase، ما يعني أنه تم تضمينها في الاستجابة ويستمر بين جلسات المستخدم.

يوضّح المثال التالي كيفية ضبط اسم معروض تلقائي:

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 نعم نعم نعم لا نعم لا
Facebook لا نعم نعم لا لا لا
Twitter لا نعم لا نعم لا لا
GitHub لا نعم لا لا لا لا
Microsoft نعم نعم نعم لا نعم لا
LinkedIn لا نعم نعم لا لا لا
Yahoo نعم نعم نعم لا نعم لا
Apple نعم نعم نعم لا نعم لا
SAML لا لا لا لا لا نعم
OIDC نعم نعم نعم لا نعم نعم

إعادة تحميل الرموز المميّزة

لاستخدام رمز مميز للتحديث في دالة حظر، يجب أولاً تحديد على صفحة وظائف الحظر في وحدة تحكُّم Firebase.

لن يعرض أي موفِّر للهوية الرموز المميّزة لإعادة التحميل أثناء تسجيل الدخول. مباشرةً باستخدام بيانات اعتماد OAuth، مثل الرمز المميز للمعرف أو رمز الدخول. في هذه الدورة، سيتم تمرير بيانات اعتماد OAuth نفسها من جهة العميل إلى دليل الأخرى.

تصف الأقسام التالية كل أنواع موفِّري الهوية ولكل أنواع موفّري الهوية المتوافقة مع هذه الأنواع. بيانات الاعتماد والبيانات.

موفِّرو OIDC العامون

عندما يسجّل المستخدم الدخول باستخدام موفِّر OIDC عام، ستظهر بيانات الاعتماد التالية سيتم تمريره:

  • الرمز المميّز للمعرّف: يتم توفيره إذا تم اختيار مسار id_token.
  • رمز الدخول: يتم توفيره عند اختيار مسار الرمز. لاحظ أن الكود البيانات المتاحة حاليًا فقط عبر واجهة برمجة تطبيقات REST.
  • الرمز المميّز لإعادة التحميل: يتم توفيره في حال نطاق 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، قارن عنوان 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". تشير رسالة الأشكال البيانية تم تخزين الرمز المميز لإعادة التحميل لإتاحة الدخول بلا اتصال.

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 للاطّلاع على مزيد من المعلومات حول دمج reCAPTCHA Enterprise مع مصادقة Firebase.

يمكن استخدام دوال الحظر للسماح بتدفقات أو حظرها استنادًا إلى عوامل مخصَّصة، وبالتالي إلغاء النتيجة المقدَّمة من reCAPTCHA Enterprise.

Node.js

 const {
   auth,
 } = require("firebase-functions/v1");

exports.checkrecaptchaV1 = auth.user().beforeSignIn((userRecord, context) => {
 // Allow users with a specific email domain to sign in regardless of their recaptcha score.
 if (userRecord.email && userRecord.email.indexOf('@acme.com') === -1) {
   return {
     recaptchaActionOverride: 'ALLOW',
   };
 }

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

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