פונקציות חסימה מאפשרות להפעיל קוד בהתאמה אישית שמשנה את התוצאה של הרשמה של משתמשים לאפליקציה או כניסה לאפליקציה. לדוגמה, תוכלו למנוע ממשתמש לבצע אימות אם הוא לא עומד בקריטריונים מסוימים, או לעדכן את פרטי המשתמש לפני החזרתו לאפליקציית הלקוח.
לפני שמתחילים
כדי להשתמש בפונקציות חסימה צריך לשדרג את פרויקט 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 תחילת העבודה). בקצרה:
כותבים פונקציה שמטפלת באירוע המטורגט.
לדוגמה, כדי להתחיל תוכלו להוסיף ל-
index.js
פונקציה מסוג no-op, כמו בדוגמה הבאה: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.
פורסים את הפונקציות באמצעות 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
| הפרויקט או הדייר ב-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 |
התנגשות מסוג בו-זמניות (Concurrency), כגון התנגשות בפעולה read-modify-write (קריאה-שינוי-כתיבה). |
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 ומוחזר ללקוח.
כדי לשנות משתמש, צריך להחזיר אובייקט מה-handler של האירועים שמכיל את השדות שרוצים לשנות. אפשר לשנות את השדות הבאים:
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';
};
});
אם רושמים handler של אירועים גם ל-beforeCreate
וגם ל-beforeSignIn
, שימו לב שה-beforeSignIn
יופעל אחרי beforeCreate
. שדות של משתמשים שעודכנו ב-beforeCreate
גלויים ב-beforeSignIn
. אם מגדירים שדה שהוא לא sessionClaims
בשני הגורמים המטפלים באירועים, הערך שהוגדר ב-beforeSignIn
יחליף את הערך שהוגדר ב-beforeCreate
. עבור sessionClaims
בלבד, הם מועברים לטענות הנכונות של האסימון של הסשן הנוכחי, אבל לא נשמרים או מאוחסנים במסד הנתונים.
לדוגמה, אם מוגדרים sessionClaims
, beforeSignIn
יחזיר אותן עם כל הצהרות beforeCreate
והן ימוזגו. כשהם ממוזגים, אם מפתח sessionClaims
תואם למפתח ב-customClaims
, המפתח התואם ב-customClaims
יימחק בהצהרות האסימון על ידי המפתח sessionClaims
. עם זאת, המפתח customClaims
המוגזם עדיין יופיע במסד הנתונים לצורך בקשות עתידיות.
פרטי כניסה ונתונים נתמכים של OAuth
אפשר להעביר פרטי כניסה ונתונים של OAuth לפונקציות חסימה מספק זהויות שונים. בטבלה הבאה אפשר לראות אילו פרטי כניסה ונתונים נתמכים לכל ספק זהויות:
ספק זהות (IdP) | אסימון מזהה | טוקן גישה | מועד תפוגה | סוד הטוקן | טוקן רענון | הצהרות על כניסה |
---|---|---|---|---|---|---|
כן | כן | כן | לא | כן | לא | |
לא | כן | כן | לא | לא | לא | |
לא | כן | לא | כן | לא | לא | |
GitHub | לא | כן | לא | לא | לא | לא |
Microsoft | כן | כן | כן | לא | כן | לא |
לא | כן | כן | לא | לא | לא | |
Yahoo | כן | כן | כן | לא | כן | לא |
Apple | כן | כן | כן | לא | כן | לא |
SAML | לא | לא | לא | לא | לא | כן |
OIDC | כן | כן | כן | לא | כן | כן |
אסימוני רענון
כדי להשתמש באסימון רענון בפונקציית חסימה, קודם צריך לסמן את תיבת הסימון בדף כלים לחסימת מודעות במסוף Firebase.
אסימוני רענון לא יחזרו על ידי ספקי זהויות כלשהם כשנכנסים לחשבון ישירות באמצעות פרטי כניסה ל-OAuth, כמו אסימון מזהה או אסימון גישה. במקרה כזה, אותם פרטי כניסה ל-OAuth מצד הלקוח יועברו לפונקציית החסימה.
בקטעים הבאים מתוארים כל סוגי ספקי הזהויות ופרטי הכניסה והנתונים הנתמכים שלהם.
ספקי OIDC גנריים
כשמשתמש נכנס באמצעות ספק OIDC גנרי, פרטי הכניסה הבאים מועברים:
- אסימון מזהה: מסופק אם נבחר התהליך
id_token
. - אסימון גישה: מסופק אם בוחרים בתהליך הקוד. חשוב לזכור שכרגע יש תמיכה בזרימת הקוד רק דרך ה-API ל-REST.
- Refresh token: אסימון שמסופק אם נבחר ההיקף
offline_access
.
דוגמה:
const provider = new firebase.auth.OAuthProvider('oidc.my-provider');
provider.addScope('offline_access');
firebase.auth().signInWithPopup(provider);
כשמשתמש נכנס באמצעות חשבון Google, פרטי הכניסה הבאים מועברים:
- אסימון מזהה
- אסימון גישה
- Refresh token: הנתון הזה מסופק רק אם מבקשים את הפרמטרים המותאמים אישית הבאים:
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, פרטי הכניסה הבאים יועברו:
- אסימון גישה
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 מגיעות מאזורים גיאוגרפיים שונים – אפשר לבקש מהמשתמש להיכנס שוב.
משתמשים בהצהרות על סשנים כדי לעקוב אחרי כתובת ה-IP שבאמצעותה המשתמש נכנס לחשבון:
Node.js
exports.beforeSignIn = functions.auth.user().beforeSignIn((user, context) => { return { sessionClaims: { signInIpAddress: context.ipAddress, }, }; });
כשמשתמש מנסה לגשת למשאבים שמחייבים אימות מול 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',
}
});