התאמה אישית של תהליך האימות באמצעות פונקציות חסימה
במאמר הזה נסביר איך להרחיב את האימות ב-Identity Platform באמצעות פונקציות Cloud Run חוסמות.
פונקציות חסימה מאפשרות להריץ קוד מותאם אישית שמשנה את התוצאה של משתמש שנרשם או נכנס לאפליקציה שלכם. לדוגמה, אתם יכולים למנוע ממשתמש לעבור אימות אם הוא לא עומד בקריטריונים מסוימים, או לעדכן את פרטי המשתמש לפני שהם מוחזרים לאפליקציית הלקוח.
לפני שמתחילים
יוצרים אפליקציה באמצעות Identity Platform. הוראות מפורטות מופיעות במאמר מדריך למתחילים.
הסבר על פונקציות חסימה
אפשר לרשום פונקציות חסימה לשני אירועים:
beforeCreate: מופעל לפני שמשתמש חדש נשמר במסד הנתונים של Identity Platform, ולפני שאסימון מוחזר לאפליקציית הלקוח.
beforeSignIn: מופעל אחרי שפרטי הכניסה של המשתמש מאומתים, אבל לפני ש-Identity Platform מחזיר טוקן מזהה לאפליקציית הלקוח. אם האפליקציה משתמשת באימות רב-שלבי, הפונקציה מופעלת אחרי שהמשתמש מאמת את השלב השני. שימו לב: יצירת משתמש חדש מפעילה גם אתbeforeSignInוגם אתbeforeCreate.
כשמשתמשים בפונקציות חסימה, חשוב לזכור את הדברים הבאים:
הפונקציה צריכה להגיב תוך שבע שניות. אחרי שבע שניות, Identity Platform מחזיר שגיאה והפעולה של הלקוח נכשלת.
קודי תגובה של HTTP שאינם
200מועברים לאפליקציות הלקוח. חשוב לוודא שקוד הלקוח מטפל בכל השגיאות שהפונקציה יכולה להחזיר.הפונקציות חלות על כל המשתמשים בפרויקט, כולל משתמשים שנמצאים בדייר. Identity Platform מספק לפונקציה מידע על המשתמשים, כולל הדיירים שהם שייכים אליהם, כדי שתוכלו להגיב בהתאם.
קישור של ספק זהויות אחר לחשבון מפעיל מחדש את כל הפונקציות הרשומות של
beforeSignIn. ההנחיה הזו לא כוללת ספקי סיסמאות וכתובות אימייל.פונקציות חסימה לא נתמכות באימות אנונימי ובאימות בהתאמה אישית.
אם אתם משתמשים גם בפונקציות אסינכרוניות, אובייקט המשתמש שפונקציה אסינכרונית מקבלת לא מכיל עדכונים מהפונקציה החוסמת.
יצירת פונקציית חסימה
בשלבים הבאים מוסבר איך ליצור פונקציית חסימה:
עוברים לדף Settings של Identity Platform במסוףGoogle Cloud .
לוחצים על הכרטיסייה טריגרים.
בהתאם למועד שבו רוצים להפעיל את פונקציית החסימה, בוחרים באפשרות Create Function מהתפריט הנפתח Before create (beforeCreate) או מהתפריט הנפתח Before sign in (beforeSignIn).
בחלונית Create function:
בשדה שם הפונקציה, מזינים שם לפונקציה.
ברשימה Region, בוחרים אזור.
מעתיקים את כתובת ה-URL של הטריגר.
בקטע Runtime, build, connections, and security settings (הגדרות של זמן ריצה, build, חיבורים ואבטחה), עוברים לכל כרטיסייה ומגדירים את ההגדרות הנדרשות.
בקטע קוד מקור, יוצרים את קוד המקור.
ברשימה Runtime בוחרים את זמן הריצה.
בשדה נקודת כניסה, מזינים את נקודת הכניסה לקוד.
בעורך המוטבע, פותחים את
index.js. מוחקים את הקוד לדוגמהhelloWorldומחליפים אותו באחד מהקודים הבאים:כדי להשיב להרשמה:
import * as gcipCloudFunctions from 'gcip-cloud-functions'; const authClient = new gcipCloudFunctions.Auth(); exports.beforeCreate = authClient.functions().beforeCreateHandler((user, context) => { });כדי להשיב לבקשת הכניסה:
import * as gcipCloudFunctions from 'gcip-cloud-functions'; const authClient = new gcipCloudFunctions.Auth(); exports.beforeSignIn = authClient.functions().beforeSignInHandler((user, context) => { });פותחים את
package.jsonומוסיפים את בלוק התלויות הבא: בקישורgcip-cloud-functionsאפשר למצוא את גרסת ה-SDK העדכנית.{ "type": "module", "name": ..., "version": ..., "dependencies": { "gcip-cloud-functions": "^0.2.0" } }
כדי לפרסם את הפונקציה, לוחצים על פריסת הפונקציה.
בוחרים את פרטי הכניסה של טוקן OAuth להעברה לפונקציה.
בדף הגדרות, לוחצים על שמירה.
אפשר גם ליצור ולנהל פונקציות באמצעות Google Cloud CLI או API בארכיטקטורת REST. הוראות מפורטות זמינות במאמרי העזרה בנושא פונקציות Cloud Run.
קבלת מידע על משתמשים והקשר
האירועים beforeSignIn ו-beforeCreate מספקים אובייקטים של User ו-EventContext
שכוללים מידע על המשתמש שנכנס לחשבון. אפשר להשתמש בערכים האלה בקוד כדי לקבוע אם לאפשר את המשך הפעולה.
רשימת המאפיינים שזמינים באובייקט User מופיעה במאמר UserRecord הפניית API.
אובייקט 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) ב-Identity Platform. |
projects/project-id/tenants/tenant-id
|
timestamp |
השעה שבה האירוע הופעל, בפורמט של מחרוזת RFC 3339. | Tue, 23 Jul 2019 21:10:57 GMT
|
additionalUserInfo |
אובייקט שמכיל מידע על המשתמש. |
AdditionalUserInfo
|
credential |
אובייקט שמכיל מידע על פרטי הכניסה של המשתמש. |
AuthCredential
|
חסימת הרשמה או כניסה
כדי לחסום ניסיון הרשמה או כניסה, צריך להקפיץ הודעת שגיאה (throw) HttpsError בפונקציה. לדוגמה:
Node.js
throw new gcipCloudFunctions.https.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 gcipCloudFunctions.https.HttpsError('permission-denied', 'Unauthorized request origin!');
בדוגמה הבאה מוסבר איך לחסום משתמשים שלא נמצאים בדומיין ספציפי מלהירשם לאפליקציה:
Node.js
// Import the Cloud Auth Admin module.
import * as gcipCloudFunctions from 'gcip-cloud-functions';
// Initialize the Auth client.
const authClient = new gcipCloudFunctions.Auth();
// Http trigger with Cloud Run functions.
exports.beforeCreate = authClient.functions().beforeCreateHandler((user, context) => {
// If the user is authenticating within a tenant context, the tenant ID can be determined from
// user.tenantId or from context.resource, eg. 'projects/project-id/tenant/tenant-id-1'
// Only users of a specific domain can sign up.
if (!user.email.endsWith('@acme.com')) {
throw new gcipCloudFunctions.https.HttpsError('invalid-argument', `Unauthorized email "${user.email}"`);
}
});
לא משנה אם משתמשים בהודעת ברירת מחדל או בהודעה מותאמת אישית, פונקציות Cloud Run עוטפות את השגיאה ומחזירות אותה ללקוח כשגיאה פנימית. לדוגמה, אם מעלים את השגיאה הבאה בפונקציה:
throw new gcipCloudFunctions.https.HttpsError('invalid-argument', `Unauthorized email user@evil.com}`);
שגיאה דומה לזו שבהמשך מוחזרת לאפליקציית הלקוח (אם אתם משתמשים ב-SDK של הלקוח, השגיאה עטופה כשגיאה פנימית):
{
"error": {
"code": 400,
"message": "BLOCKING_FUNCTION_ERROR_RESPONSE : HTTP Cloud Function returned an error. Code: 400, Status: \"INVALID_ARGUMENT\", Message: \"Unauthorized email user@evil.com\"",
"errors": [
{
"message": "BLOCKING_FUNCTION_ERROR_RESPONSE : HTTP Cloud Function returned an error. Code: 400, Status: \"INVALID_ARGUMENT\", Message: \"Unauthorized email user@evil.com\"",
"domain": "global",
"reason": "invalid"
}
]
}
}
האפליקציה צריכה לזהות את השגיאה ולטפל בה בהתאם. לדוגמה:
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 שנשמר במסד הנתונים של Identity Platform ומוחזר ללקוח.
כדי לשנות משתמש, מחזירים אובייקט מ-גורם מטפל באירועים שמכיל את השדות שרוצים לשנות. אפשר לשנות את השדות הבאים:
displayNamedisabledemailVerifiedphotoURLcustomClaims-
sessionClaims(beforeSignInבלבד)
למעט sessionClaims, כל השדות שמשתנים נשמרים במסד הנתונים של Identity Platform, כלומר הם נכללים באסימון התגובה ונשמרים בין פעילויות של משתמשים.
בדוגמה הבאה אפשר לראות איך מגדירים שם לתצוגה כברירת מחדל:
Node.js
exports.beforeCreate = authClient.functions().beforeCreateHandler((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 ונתונים לפונקציות חסימה מספקי זהויות שונים. בטבלה הבאה מפורטים סוגי האישורים והנתונים שנתמכים בכל ספק זהויות:
| ספק הזהות | טוקן מזהה | טוקן גישה | מועד תפוגה | סוד הטוקן | רענון הטוקן | הצהרות על כניסה לחשבון |
|---|---|---|---|---|---|---|
| כן | כן | כן | לא | כן | לא | |
| לא | כן | כן | לא | לא | לא | |
| לא | כן | לא | כן | לא | לא | |
| GitHub | לא | כן | לא | לא | לא | לא |
| Microsoft | כן | כן | כן | לא | כן | לא |
| לא | כן | כן | לא | לא | לא | |
| Yahoo | כן | כן | כן | לא | כן | לא |
| Apple | כן | כן | כן | לא | כן | לא |
| SAML | לא | לא | לא | לא | לא | כן |
| OIDC | כן | כן | כן | לא | כן | כן |
אסימוני רענון
כדי להשתמש בטוקן לרענון בפונקציה חוסמת, קודם צריך לסמן את תיבת הסימון Include token credentials (הכללת פרטי כניסה של טוקן) בתפריט הנפתח Triggers (טריגרים) במסוף Google Cloud .
ספקי זהויות לא יחזירו אסימוני רענון כשמתחברים ישירות באמצעות פרטי כניסה של OAuth, כמו אסימון מזהה או אסימון גישה. במצב הזה, אותם פרטי כניסה של OAuth בצד הלקוח יועברו לפונקציית החסימה. עם זאת, בתהליכי אימות עם 3 רגליים, יכול להיות שאסימון רענון יהיה זמין אם ספק הזהויות תומך בו.
בקטעים הבאים מתוארים כל סוגי ספקי הזהויות, פרטי הכניסה והנתונים שהם תומכים בהם.
ספקי OIDC גנריים
כשמשתמש נכנס לחשבון באמצעות ספק OIDC כללי, פרטי הכניסה הבאים מועברים:
- ID token: מסופק אם נבחר התהליך
id_token. - אסימון גישה: מוצג אם נבחר תהליך הקוד. הערה: תהליך העברת הקוד נתמך רק ב-API בארכיטקטורת REST.
- אסימון רענון: האסימון הזה מסופק אם נבחר היקף ההרשאות
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
כשמשתמש נכנס לחשבון באמצעות 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 = authClient.functions().beforeCreateHandler((user, context) => {
if (!user.email || user.email.indexOf('@example.com') === -1) {
throw new gcipCloudFunctions.https.HttpsError(
'invalid-argument', `Unauthorized email "${user.email}"`);
}
});
חסימת משתמשים עם כתובות אימייל לא מאומתות מלהירשם
בדוגמה הבאה מוצג איך למנוע ממשתמשים עם כתובות אימייל לא מאומתות להירשם לאפליקציה:
Node.js
exports.beforeCreate = authClient.functions().beforeCreateHandler((user, context) => {
if (user.email && !user.emailVerified) {
throw new gcipCloudFunctions.https.HttpsError(
'invalid-argument', `Unverified email "${user.email}"`);
}
});
חובת אימות של כתובת האימייל לפני ההרשמה
בדוגמה הבאה אפשר לראות איך דורשים ממשתמש לאמת את כתובת האימייל שלו אחרי ההרשמה:
Node.js
exports.beforeCreate = authClient.functions().beforeCreateHandler((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 = authClient.functions().beforeSignInHandler((user, context) => {
if (user.email && !user.emailVerified) {
throw new gcipCloudFunctions.https.HttpsError(
'invalid-argument', `"${user.email}" needs to be verified before access is granted.`);
}
});
התייחסות לאימיילים מסוימים מספק הזהויות כאל אימיילים מאומתים
בדוגמה הבאה אפשר לראות איך להתייחס לאימיילים של משתמשים מספקי זהויות מסוימים כאל אימיילים מאומתים:
Node.js
exports.beforeCreate = authClient.functions().beforeCreateHandler((user, context) => {
if (user.email && !user.emailVerified && context.eventType.indexOf(':facebook.com') !== -1) {
return {
emailVerified: true,
};
}
});
חסימה של כניסה מכתובות IP מסוימות
בדוגמה הבאה מוצג איך לחסום כניסות מטווחים מסוימים של כתובות IP.
Node.js
exports.beforeSignIn = authClient.functions().beforeSignInHandler((user, context) => {
if (isSuspiciousIpAddress(context.ipAddress)) {
throw new gcipCloudFunctions.https.HttpsError(
'permission-denied', 'Unauthorized access!');
}
});
הגדרת טענות מותאמות אישית וטענות של סשן
בדוגמה הבאה מוצגות הגדרות של הצהרות מותאמות אישית והצהרות של סשן:
Node.js
exports.beforeCreate = authClient.functions().beforeCreateHandler((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 = authClient.functions().beforeSignInHandler((user, context) => { return { sessionClaims: { signInIpAddress: context.ipAddress, }, }; });כשמשתמש מנסה לגשת למשאבים שנדרש אימות כדי לגשת אליהם באמצעות Identity Platform, צריך להשוות את כתובת ה-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 = authClient.functions().beforeCreateHandler((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');
const gcipCloudFunctions = require('gcip-cloud-functions');
// ...
// Initialize Google OAuth client.
const keys = require('./oauth2.keys.json');
const oAuth2Client = new OAuth2Client(
keys.web.client_id,
keys.web.client_secret
);
exports.beforeCreate = authClient.functions().beforeCreateHandler((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();
});
});
})
}
});
המאמרים הבאים
- הרחבת האימות באמצעות פונקציות אסינכרוניות.
- מידע נוסף על פונקציות Cloud Run