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


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

قبل ان تبدأ

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

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

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

  • 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 CLI:

    firebase deploy --only functions
    

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

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

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

للحصول على قائمة بالخصائص المتوفرة في كائن User ، راجع مرجع UserRecord API .

يحتوي كائن EventContext على الخصائص التالية:

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

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

  • 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 وبياناته لحظر الوظائف من موفري الهوية المختلفين. يوضح الجدول التالي بيانات الاعتماد والبيانات المدعومة لكل موفر هوية:

موفر الهوية رمز الهوية رمز وصول تاريخ انتهاء الصلاحية سر الرمز تحديث الرمز المميز مطالبات تسجيل الدخول
جوجل نعم نعم نعم لا نعم لا
فيسبوك لا نعم نعم لا لا لا
تويتر لا نعم لا نعم لا لا
جيثب لا نعم لا لا لا لا
مايكروسوفت نعم نعم نعم لا نعم لا
ينكدين لا نعم نعم لا لا لا
ياهو نعم نعم نعم لا نعم لا
تفاحة نعم نعم نعم لا نعم لا
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، سيتم تمرير بيانات الاعتماد التالية:

  • رمز الهوية
  • رمز وصول
  • رمز التحديث : يتم توفيره فقط في حالة طلب المعلمات المخصصة التالية:
    • access_type=offline
    • prompt=consent ، إذا وافق المستخدم مسبقًا ولم يتم طلب نطاق جديد

مثال:

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

تعرف على المزيد حول الرموز المميزة لتحديث Google .

فيسبوك

عندما يقوم المستخدم بتسجيل الدخول باستخدام الفيسبوك، سيتم تمرير بيانات الاعتماد التالية:

جيثب

عندما يقوم مستخدم بتسجيل الدخول باستخدام GitHub، سيتم تمرير بيانات الاعتماد التالية:

  • رمز الوصول : لا تنتهي صلاحيته إلا إذا تم إلغاؤه.

مايكروسوفت

عندما يقوم مستخدم بتسجيل الدخول باستخدام Microsoft، سيتم تمرير بيانات الاعتماد التالية:

  • رمز الهوية
  • رمز وصول
  • رمز التحديث : يتم تمريره إلى وظيفة الحظر إذا تم تحديد نطاق offline_access .

مثال:

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

ياهو

عندما يقوم مستخدم بتسجيل الدخول باستخدام Yahoo، سيتم تمرير بيانات الاعتماد التالية دون أي معلمات أو نطاقات مخصصة:

  • رمز الهوية
  • رمز وصول
  • تحديث الرمز المميز

ينكدين

عندما يقوم المستخدم بتسجيل الدخول باستخدام LinkedIn، سيتم تمرير بيانات الاعتماد التالية:

  • رمز وصول

تفاحة

عندما يقوم مستخدم بتسجيل الدخول باستخدام 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',
 };
});