טריגרים לחסימת אימות (דור ראשון)

פונקציות חסימה מאפשרות להריץ קוד בהתאמה אישית שמשנה את התוצאה של רישום או כניסה של משתמש לאפליקציה. לדוגמה, אפשר למנוע ממשתמש לבצע אימות אם הוא לא עומד בקריטריונים מסוימים, או לעדכן את פרטי המשתמש לפני שהם מוחזרים לאפליקציית הלקוח.

לפני שמתחילים

כדי להשתמש בפונקציות חסימה, צריך לשדרג את פרויקט Firebase ל-Firebase Authentication with Identity Platform. אם עדיין לא שדרגתם, קודם צריך לשדרג.

הסבר על פונקציות חסימה

אפשר לרשום פונקציות חסימה לאירועים הבאים:

  • ‫beforeCreate: מופעל לפני שמשתמש חדש נשמר במסד הנתונים של Firebase Authentication, ולפני שאסימון מוחזר לאפליקציית הלקוח.

  • ‫beforeSignIn: מופעל אחרי שפרטי הכניסה של המשתמש מאומתים, אבל לפני ש-Firebase Authentication מחזיר טוקן של מזהה לאפליקציית הלקוח. אם האפליקציה משתמשת באימות רב-שלבי, הפונקציה מופעלת אחרי שהמשתמש מאמת את הגורם השני. חשוב לשים לב שיצירת משתמש חדש מפעילה גם את beforeSignIn, בנוסף ל-beforeCreate.

  • ‫beforeEmail (Node.js בלבד): מופעל לפני שאימייל (לדוגמה,
    אימייל לכניסה או לאיפוס סיסמה) נשלח למשתמש.

  • ‫beforeSms (Node.js בלבד): מופעל לפני שליחת הודעת SMS למשתמש, במקרים כמו אימות רב-שלבי.

כשמשתמשים בפונקציות חסימה, חשוב לזכור את הדברים הבאים:

  • הפונקציה צריכה להגיב תוך 7 שניות. אחרי 7 שניות, הפונקציה Firebase Authentication מחזירה שגיאה והפעולה של הלקוח נכשלת.

  • קודי תגובה של HTTP שהם לא 200 מועברים לאפליקציות הלקוח. חשוב לוודא שקוד הלקוח מטפל בכל השגיאות שהפונקציה יכולה להחזיר.

  • הפונקציות חלות על כל המשתמשים בפרויקט, כולל אלה שכלולים בדייר. ‫Firebase Authentication מספק לפונקציה מידע על המשתמשים, כולל הדיירים שהם שייכים אליהם, כדי שתוכלו להגיב בהתאם.

  • קישור של ספק זהויות אחר לחשבון מפעיל מחדש את כל הפונקציות הרשומות של beforeSignIn.

  • אימות אנונימי ואימות בהתאמה אישית לא מפעילים פונקציות חסימה.

פריסת פונקציית חסימה

כדי להוסיף את הקוד המותאם אישית לתהליכי אימות המשתמשים, צריך לפרוס פונקציות חסימה. אחרי שפורסים את פונקציות החסימה, הקוד בהתאמה אישית צריך לפעול בצורה תקינה כדי שהאימות ויצירת המשתמש יצליחו.

פורסים פונקציית חסימה באותו אופן שבו פורסים כל פונקציה אחרת. (פרטים נוספים זמינים בדף Cloud Functions תחילת העבודה). בקצרה:

  1. כותבים פונקציה שמטפלת באירוע המטורגט.

    לדוגמה, כדי להתחיל, אפשר להוסיף פונקציית no-op כמו זו שבהמשך אל 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. פורסים את הפונקציות באמצעות ה-CLI של Firebase:

    firebase deploy --only functions
    

    צריך לפרוס מחדש את הפונקציות בכל פעם שמעדכנים אותן.

קבלת מידע על המשתמש ועל ההקשר

האירועים beforeSignIn ו-beforeCreate מספקים אובייקטים מסוג User ו-EventContext שמכילים מידע על המשתמש שנכנס לחשבון. אתם יכולים להשתמש בערכים האלה בקוד כדי לקבוע אם לאפשר לפעולה להמשיך.

לרשימה של המאפיינים שזמינים באובייקט User, אפשר לעיין במאמרי העזרה של ה-API של UserRecord.

האובייקט EventContext מכיל את המאפיינים הבאים:

שם תיאור דוגמה
locale הלוקאל של האפליקציה. אפשר להגדיר את הלוקאל באמצעות ה-SDK של הלקוח, או על ידי העברת הכותרת של הלוקאל ב-API בארכיטקטורת 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 הפרויקט או הדייר (tenant) ב-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 שיטת ה-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}`);

האפליקציה צריכה לזהות את השגיאה ולטפל בה בהתאם. לדוגמה:

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 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 לפונקציות חסימה מספקי זהויות שונים. בטבלה הבאה מפורטים פרטי הכניסה והנתונים שנתמכים בכל ספק זהויות:

ספק זהות (IdP) טוקן של מזהה טוקן גישה מועד תפוגה סוד הטוקן טוקן רענון הצהרות כניסה
Google כן כן כן לא כן לא
Facebook לא כן כן לא לא לא
Twitter לא כן לא כן לא לא
GitHub לא כן לא לא לא לא
Microsoft כן כן כן לא כן לא
LinkedIn לא כן כן לא לא לא
Yahoo כן כן כן לא כן לא
Apple כן כן כן לא כן לא
SAML לא לא לא לא לא כן
OIDC כן כן כן לא כן כן

אסימוני רענון

כדי להשתמש בטוקן רענון בפונקציית חסימה, קודם צריך לסמן את תיבת הסימון בדף Blocking functions במסוף Firebase (עוברים אל Security > Authentication > הכרטיסייה Settings).

ספקי זהויות לא יחזירו טוקני רענון כשנכנסים ישירות באמצעות פרטי כניסה של OAuth, כמו טוקן של מזהה או טוקן גישה. במצב כזה, אותם פרטי כניסה של OAuth בצד הלקוח יועברו לפונקציית החסימה.

בקטעים הבאים מתוארים כל סוגי ספקי הזהויות, ופרטי הכניסה והנתונים שהם תומכים בהם.

ספקי OIDC גנריים

כשמשתמש נכנס באמצעות ספק OIDC כללי, פרטי הכניסה הבאים מועברים:

  • טוקן של מזהה: מסופק אם נבחר התהליך id_token.
  • טוקן גישה: מסופק אם נבחר תהליך הקוד. שימו לב שכרגע, תהליך הקוד נתמך רק דרך ה-API בארכיטקטורת 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

כשמשתמש נכנס באמצעות פייסבוק, פרטי הכניסה הבאים מועברים:

  • טוקן גישה: מוחזר טוקן גישה שאפשר להחליף בטוקן גישה אחר. מידע נוסף על הסוגים השונים של טוקני גישה שנתמכים על ידי פייסבוק, ואיך להחליף אותם בטוקנים לטווח ארוך.

GitHub

כשמשתמש נכנס באמצעות GitHub, פרטי הכניסה הבאים מועברים:

  • טוקן גישה: לא פג תוקף אלא אם הוא מבוטל.

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, ולהשתמש בו כדי לשלוח קריאה לממשקי ה-API של יומן 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 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',
 }
});