ערכות Firebase Data Connect admin SDK מאפשרות לכם להפעיל את השאילתות והמוטציות שלכם מסביבות מהימנות כמו Cloud Functions, קצה עורפי בהתאמה אישית או תחנת עבודה משלכם. בדומה ליצירת ערכות SDK לאפליקציות הלקוח, אפשר ליצור במקביל ערכת SDK מותאמת אישית לאדמין בזמן שמעצבים את הסכימות, השאילתות והמוטציות שפורסים בשירות Data Connect. לאחר מכן, מטמיעים שיטות מתוך ה-SDK הזה בלוגיקה של ה-Backend או בסקריפטים של הניהול.
כפי שציינו במקומות אחרים, חשוב לדעת ששאילתות ומוטציות של Data Connect לא נשלחות על ידי לקוחות בזמן הבקשה. במקום זאת, כשפורסים את Data Connect, הפעולות שלו מאוחסנות בשרת כמו Cloud Functions. המשמעות היא שבכל פעם שמבצעים פריסה של שינויים בשאילתות ובמוטציות, צריך גם ליצור מחדש את ה-Admin SDK ולפרוס מחדש את כל השירותים שמסתמכים עליו.
לפני שמתחילים
- מידע על עיצוב סכימות, שאילתות ומוטציות של Data Connect בתהליך עבודה טיפוסי, מפתחים אותם במקביל לקוד האפליקציה, כולל שירותים שמשתמשים ב-SDK של Admin.
- מתקינים את Firebase CLI.
- כוללים את Admin SDK ל-Node.js כתלות בכל מקום שבו מתכננים לקרוא ל-Admin SDK שנוצרו.
יצירת SDK לאדמינים
אחרי שיוצרים את הסכימות, השאילתות והמוטציות של Data Connect, אפשר ליצור SDK תואם לניהול:
פותחים או יוצרים קובץ
connector.yamlומוסיפים הגדרה שלadminNodeSdk:connectorId: default generate: adminNodeSdk: outputDir: ../../dataconnect-generated/admin-generated package: "@dataconnect/admin-generated" packageJsonDir: ../..קובץ
connector.yamlנמצא בדרך כלל באותה ספרייה שבה נמצאים קובצי GraphQL (.gql) שמכילים את ההגדרות של השאילתה והמוטציה. אם כבר יצרתם ערכות SDK ללקוח, הקובץ הזה כבר נוצר.יוצרים את ה-SDK.
אם התקנתם את התוסף Data Connect VS Code, הוא תמיד ידאג לעדכן את ערכות ה-SDK שנוצרו.
אחרת, משתמשים ב-Firebase CLI:
firebase dataconnect:sdk:generateלחלופין, כדי ליצור מחדש באופן אוטומטי ערכות SDK כשמעדכנים את קובצי
gql:firebase dataconnect:sdk:generate --watch
ביצוע פעולות מ-Admin SDK
Admin SDK שנוצר מכיל ממשקים ופונקציות שתואמים להגדרות של gql, ואפשר להשתמש בהם כדי לבצע פעולות במסד הנתונים. לדוגמה, נניח שיצרתם SDK למסד נתונים של שירים, יחד עם שאילתה, getSongs:
import { initializeApp } from "firebase-admin/app";
import { getSongs } from "@dataconnect/admin-generated";
const adminApp = initializeApp();
const songs = await getSongs(
{ limit: 4 },
{ impersonate: { unauthenticated: true } }
);
לחלופין, כדי לציין הגדרות אישיות של מחבר:
import { initializeApp } from "firebase-admin/app";
import { getDataConnect } from "firebase-admin/data-connect";
import {
connectorConfig,
getSongs,
} from "@dataconnect/admin-generated";
const adminApp = initializeApp();
const adminDc = getDataConnect(connectorConfig);
const songs = await getSongs(
adminDc,
{ limit: 4 },
{ impersonate: { unauthenticated: true } }
);
התחזות למשתמש לא מאומת
ערכות ה-SDK לאדמינים מיועדות להרצה בסביבות מהימנות, ולכן יש להן גישה בלתי מוגבלת למסדי הנתונים שלכם.
כשמריצים פעולות ציבוריות באמצעות Admin SDK, מומלץ להימנע מהרצת הפעולה עם הרשאות אדמין מלאות (בהתאם לעיקרון של הרשאות מינימליות). במקום זאת, צריך להריץ את הפעולה כמשתמש עם התחזות (ראו את הקטע הבא) או כמשתמש לא מאומת עם התחזות.
משתמשים לא מאומתים יכולים להריץ רק פעולות שמסומנות ב-PUBLIC.
בדוגמה שלמעלה, השאילתה getSongs מופעלת כמשתמש לא מאומת.
התחברות זמנית כמשתמש אחר
אפשר גם לבצע פעולות בשם משתמשים ספציפיים על ידי העברת חלק מאסימון Firebase Authentication או את כולו באפשרות impersonate. לכל הפחות, צריך לציין את מזהה המשתמש של המשתמש בתביעת המשנה. (זה אותו ערך כמו ערך השרת auth.uid שאפשר להפנות אליו בפעולות GraphQL של Data Connect).
כשמבצעים התחזות למשתמש, הפעולה תצליח רק אם נתוני המשתמש שסיפקתם יעברו את בדיקות האימות שצוינו בהגדרת GraphQL.
אם אתם קוראים ל-SDK שנוצר מנקודת קצה (endpoint) שנגישה לציבור, חשוב מאוד שנקודת הקצה תדרוש אימות ושתוודאו את תקינות טוקן האימות לפני שתשתמשו בו כדי להתחזות למשתמש.
כשמשתמשים ב-Cloud Functions שאפשר להפעיל, טוקן האימות מאומת באופן אוטומטי ואפשר להשתמש בו כמו בדוגמה הבאה:
import { HttpsError, onCall } from "firebase-functions/https";
export const callableExample = onCall(async (req) => {
const authClaims = req.auth?.token;
if (!authClaims) {
throw new HttpsError("unauthenticated", "Unauthorized");
}
const favoriteSongs = await getMyFavoriteSongs(
undefined,
{ impersonate: { authClaims } }
);
// ...
});
אחרת, צריך להשתמש בשיטה Admin SDK של verifyIdToken כדי לאמת ולפענח את טוקן האימות. לדוגמה, נניח שנקודת הקצה שלכם מיושמת כפונקציית HTTP רגילה והעברתם את אסימון Firebase Authentication לנקודת הקצה באמצעות הכותרת authorization, כמו שקורה בדרך כלל:
import { getAuth } from "firebase-admin/auth";
import { onRequest } from "firebase-functions/https";
const auth = getAuth();
export const httpExample = onRequest(async (req, res) => {
const token = req.header("authorization")?.replace(/^bearer\s+/i, "");
if (!token) {
res.sendStatus(401);
return;
}
let authClaims;
try {
authClaims = await auth.verifyIdToken(token);
} catch {
res.sendStatus(401);
return;
}
const favoriteSongs = await getMyFavoriteSongs(
undefined,
{ impersonate: { authClaims } }
);
// ...
});
רק כשמבצעים משימות ניהול אמיתיות, כמו העברת נתונים, מסביבה מאובטחת שלא נגישה לציבור, צריך לציין מזהה משתמש שלא הגיע ממקור שניתן לאימות:
// Never do this if end users can initiate execution of the code!
const favoriteSongs = await getMyFavoriteSongs(
undefined,
{ impersonate: { authClaims } }
);
הפעלה עם גישה בלתי מוגבלת
אם מבצעים פעולה שדורשת הרשאות ברמת האדמין, צריך להשמיט את הפרמטר impersonate מהקריאה:
await upsertSong(adminDc, {
title: songTitle_one,
instrumentsUsed: [Instrument.VOCAL],
});
לפעולה שמופעלת בצורה הזו יש גישה מלאה למסד הנתונים. אם יש לכם שאילתות או מוטציות שמיועדות לשימוש למטרות ניהול בלבד, אתם צריכים להגדיר אותן באמצעות ההנחיה @auth(level: NO_ACCESS). כך מבטיחים שרק משתמשים עם הרשאת אדמין יוכלו לבצע את הפעולות האלה.