בדוק את כללי האבטחה של Cloud Firestore שלך

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

התחלה מהירה

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

הבן את כללי האבטחה של Cloud Firestore

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

כללי האבטחה של Cloud Firestore כוללים שני חלקים:

  1. הצהרת match המזהה מסמכים במסד הנתונים שלך.
  2. ביטוי allow השולט בגישה לאותם מסמכים.

אימות Firebase מאמת את אישורי המשתמשים ומספק את הבסיס למערכות גישה מבוססות-משתמש ותפקידים.

כל בקשת מסד נתונים מספריית Cloud Firestore לנייד/אינטרנט מוערכת מול כללי האבטחה שלך לפני קריאה או כתיבה של נתונים כלשהם. אם הכללים מונעים גישה לכל אחד מנתיבי המסמכים שצוינו, הבקשה כולה נכשלת.

למידע נוסף על כללי האבטחה של Cloud Firestore ב- תחילת העבודה עם כללי האבטחה של Cloud Firestore .

התקן את האמולטור

כדי להתקין את אמולטור Cloud Firestore, השתמש ב- Firebase CLI והפעל את הפקודה למטה:

firebase setup:emulators:firestore

הפעל את האמולטור

התחל באתחול פרויקט Firebase בספריית העבודה שלך. זהו שלב ראשון שכיח בעת שימוש ב-Firebase CLI .

firebase init

הפעל את האמולטור באמצעות הפקודה הבאה. האמולטור יפעל עד שתהרוג את התהליך:

firebase emulators:start --only firestore

במקרים רבים אתה רוצה להפעיל את האמולטור, להפעיל חבילת בדיקה ולאחר מכן לכבות את האמולטור לאחר הפעלת הבדיקות. אתה יכול לעשות זאת בקלות באמצעות הפקודה emulators:exec :

firebase emulators:exec --only firestore "./my-test-script.sh"

עם הפעלת האמולטור ינסה לפעול על יציאת ברירת מחדל (8080). אתה יכול לשנות את יציאת האמולטור על ידי שינוי הקטע "emulators" בקובץ firebase.json שלך:

{
  // ...
  "emulators": {
    "firestore": {
      "port": "YOUR_PORT"
    }
  }
}

לפני שתפעיל את האמולטור

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

  • האמולטור יטען בתחילה את הכללים שצוינו בשדה firestore.rules של קובץ firebase.json שלך. הוא מצפה לשם של קובץ מקומי המכיל את כללי האבטחה של Cloud Firestore שלך ​​ומחיל את הכללים האלה על כל הפרויקטים. אם אינך מספק את נתיב הקובץ המקומי או משתמש בשיטת loadFirestoreRules כמתואר להלן, האמולטור מתייחס לכל הפרויקטים כבעלי כללים פתוחים.
  • בעוד שרוב ערכות ה-SDK של Firebase פועלות ישירות עם האמולטורים, רק ספריית @firebase/rules-unit-testing תומכת auth לעגנית בכללי אבטחה, מה שהופך את בדיקות היחידה להרבה יותר קלות. בנוסף, הספרייה תומכת בכמה תכונות ספציפיות לאמולטור כמו ניקוי כל הנתונים, כמפורט להלן.
  • האמולטורים יקבלו גם אסימוני Firebase Auth המסופקים דרך Client SDK ויעריכו חוקים בהתאם, מה שמאפשר לחבר את האפליקציה שלך ישירות לאמולטורים באינטגרציה ובבדיקות ידניות.

הפעל בדיקות יחידה מקומית

הפעל בדיקות יחידות מקומיות עם v9 JavaScript SDK

Firebase מפיצה ספריית בדיקות יחידת כללי אבטחה עם גרסה 9 JavaScript SDK שלה וגרסה 8 SDK. ממשקי ה-API של הספרייה שונים באופן משמעותי. אנו ממליצים על ספריית הבדיקות v9, שהיא יותר יעילה ודורשת פחות הגדרות כדי להתחבר לאמולטורים ובכך להימנע בבטחה משימוש מקרי במשאבי ייצור. עבור תאימות לאחור, אנו ממשיכים להפוך את ספריית הבדיקות v8 לזמינה .

השתמש במודול @firebase/rules-unit-testing כדי ליצור אינטראקציה עם האמולטור שפועל באופן מקומי. אם אתה מקבל פסק זמן או שגיאות ECONNREFUSED , בדוק שוב שהאמולטור אכן פועל.

אנו ממליצים בחום להשתמש בגרסה עדכנית של Node.js כדי שתוכל להשתמש בסימון async/await . כמעט כל ההתנהגות שאולי תרצה לבדוק כוללת פונקציות אסינכרוניות, ומודול הבדיקה נועד לעבוד עם קוד מבוסס הבטחה.

ספריית V9 Rules Unit Testing מודעת תמיד לאמולטורים ולעולם לא נוגעת במשאבי הייצור שלך.

אתה מייבא את הספרייה באמצעות הצהרות ייבוא ​​מודולריות של v9. לדוגמה:

import {
  assertFails,
  assertSucceeds,
  initializeTestEnvironment
} from "@firebase/rules-unit-testing"

// Use `const { … } = require("@firebase/rules-unit-testing")` if imports are not supported
// Or we suggest `const testing = require("@firebase/rules-unit-testing")` if necessary.

לאחר הייבוא, יישום בדיקות יחידה כולל:

  • יצירה והגדרה של RulesTestEnvironment עם קריאה לאתחול initializeTestEnvironment .
  • הגדרת נתוני בדיקה מבלי להפעיל כללים, באמצעות שיטת נוחות המאפשרת לך לעקוף אותם באופן זמני, RulesTestEnvironment.withSecurityRulesDisabled .
  • הגדרת חבילת בדיקה ולכל בדיקה לפני/אחרי הוקס עם קריאות לניקוי נתוני בדיקה וסביבת, כמו RulesTestEnvironment.cleanup() או RulesTestEnvironment.clearFirestore() .
  • יישום מקרי בדיקה המחקים מצבי אימות באמצעות RulesTestEnvironment.authenticatedContext ו- RulesTestEnvironment.unauthenticatedContext .

שיטות נפוצות ופונקציות שירות

ראה גם שיטות בדיקה ספציפיות לאמולטור ב-v9 SDK .

initializeTestEnvironment() => RulesTestEnvironment

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

הפונקציה מקבלת אובייקט אופציונלי המגדיר TestEnvironmentConfig , שיכול להכיל מזהה פרויקט והגדרות תצורת אמולטור.

let testEnv = await initializeTestEnvironment({
  projectId: "demo-project-1234",
  firestore: {
    rules: fs.readFileSync("firestore.rules", "utf8"),
  },
});

RulesTestEnvironment.authenticatedContext({ user_id: string, tokenOptions?: TokenOptions }) => RulesTestContext

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

השתמש באובייקט ההקשר של הבדיקה שהוחזר בבדיקות שלך כדי לגשת לכל מופעי האמולטור שהוגדרו, כולל אלה שהוגדרו עם initializeTestEnvironment .

// Assuming a Firestore app and the Firestore emulator for this example
import { setDoc } from "firebase/firestore";

const alice = testEnv.authenticatedContext("alice", { … });
// Use the Firestore instance associated with this context
await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });

RulesTestEnvironment.unauthenticatedContext() => RulesTestContext

שיטה זו יוצרת RulesTestContext , שמתנהג כמו לקוח שאינו מחובר באמצעות אימות. לבקשות שנוצרו באמצעות ההקשר המוחזר לא יצורפו אסימוני Firebase Auth.

השתמש באובייקט ההקשר של הבדיקה שהוחזר בבדיקות שלך כדי לגשת לכל מופעי האמולטור שהוגדרו, כולל אלה שהוגדרו עם initializeTestEnvironment .

// Assuming a Cloud Storage app and the Storage emulator for this example
import { getStorage, ref, deleteObject } from "firebase/storage";

const alice = testEnv.unauthenticatedContext();

// Use the Cloud Storage instance associated with this context
const desertRef = ref(alice.storage(), 'images/desert.jpg');
await assertSucceeds(deleteObject(desertRef));

RulesTestEnvironment.withSecurityRulesDisabled()

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

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

RulesTestEnvironment.cleanup()

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

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

assertSucceeds(pr: Promise<any>)) => Promise<any>

זוהי פונקציית עזר למקרה מבחן.

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

await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });

assertFails(pr: Promise<any>)) => Promise<any>

זוהי פונקציית עזר למקרה מבחן.

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

await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });

שיטות ספציפיות לאמולטור

ראה גם שיטות בדיקה נפוצות ופונקציות שירות ב-v9 SDK .

RulesTestEnvironment.clearFirestore() => Promise<void>

שיטה זו מנקה נתונים במסד הנתונים של Firestore השייכים ל- projectId שהוגדר עבור אמולטור Firestore.

RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;

שיטה זו מקבלת מופע Firestore עבור הקשר בדיקה זה. ניתן להשתמש במופע Firebase JS Client SDK המוחזר עם ממשקי API של הלקוח SDK (v9 מודולרי או v9 compat).

דמיינו הערכות כללים

אמולטור Cloud Firestore מאפשר לך לדמיין בקשות לקוח בממשק המשתמש של Emulator Suite, כולל מעקב אחר הערכה עבור כללי האבטחה של Firebase.

פתח את הכרטיסייה Firestore > בקשות כדי להציג את רצף ההערכה המפורט עבור כל בקשה.

Firestore Emulator Requests Monitor המציג הערכות כללי אבטחה

הפקת דוחות בדיקה

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

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

http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage.html

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

http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage

הבדלים בין האמולטור לייצור

  1. אינך חייב ליצור במפורש פרויקט Cloud Firestore. האמולטור יוצר אוטומטית כל מופע שניגשת אליו.
  2. אמולטור Cloud Firestore לא עובד עם זרימת האימות הרגילה של Firebase. במקום זאת, ב-Firebase Test SDK, סיפקנו את שיטת initializeTestApp() בספריית ה- rules-unit-testing , אשר לוקחת שדה auth . הידית של Firebase שנוצרה בשיטה זו תתנהג כאילו היא אומתה בהצלחה בתור כל ישות שתספק. אם תעביר ב- null , הוא יתנהג כמשתמש לא מאומת (חוקי auth != null ייכשלו, למשל).

פתרון בעיות ידועות

כשאתה משתמש באמולטור Cloud Firestore, אתה עלול להיתקל בבעיות הידועות הבאות. עקוב אחר ההנחיות שלהלן כדי לפתור כל התנהגות לא סדירה שאתה חווה. הערות אלה נכתבו מתוך מחשבה על ספריית הבדיקות של יחידת כללי האבטחה, אך הגישות הכלליות חלות על כל Firebase SDK.

התנהגות הבדיקה אינה עקבית

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

בפרט, סקור את פעולות הסנכרון הבאות:

  • הגדרת כללי אבטחה, עם, למשל, initializeTestEnvironment .
  • קריאה וכתיבה של נתונים, עם, למשל, db.collection("users").doc("alice").get() .
  • הצהרות תפעוליות, כולל assertSucceeds ו- assertFails .

המבחנים עוברים רק בפעם הראשונה שאתה טוען את האמולטור

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

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

הגדרת הבדיקה היא מאוד מסובכת

בעת הגדרת הבדיקה שלך, ייתכן שתרצה לשנות נתונים באופן שחוקי האבטחה שלך ב-Cloud Firestore אינם מאפשרים בפועל. אם הכללים שלך הופכים את הגדרת הבדיקה למורכבת, נסה להשתמש ב- RulesTestEnvironment.withSecurityRulesDisabled בשלבי ההגדרה שלך, כך שקריאה וכתיבה לא יפעילו שגיאות PERMISSION_DENIED .

לאחר מכן, הבדיקה שלך יכולה לבצע פעולות כמשתמש מאומת או לא מאומת באמצעות RulesTestEnvironment.authenticatedContext ו- unauthenticatedContext בהתאמה. זה מאפשר לך לאמת שכללי האבטחה של Cloud Firestore שלך ​​מאפשרים / שוללים מקרים שונים בצורה נכונה.