Cloud Firestore Security Rules מאפשרים לכם לשלוט בגישה למסמכים ולאוספים במסד הנתונים. תחביר הכללים הגמיש מאפשר ליצור כללים שתואמים לכל דבר, החל מכל הכתיבות במסד הנתונים כולו ועד לפעולות במסמך ספציפי.
במדריך הזה מתוארים התחביר והמבנה הבסיסיים של כללי האבטחה. משלבים את התחביר הזה עם תנאים של כללי אבטחה כדי ליצור קבוצות כללים מלאות.
הצהרה על שירותים ומסדי נתונים
Cloud Firestore Security Rules תמיד מתחילה בהצהרה הבאה:
service cloud.firestore {
match /databases/{database}/documents {
// ...
}
}
ההצהרה service cloud.firestore
מגבילה את ההיקף של הכללים ל-Cloud Firestore, כדי למנוע התנגשויות בין Cloud Firestore Security Rules לבין כללים של מוצרים אחרים, כמו Cloud Storage.
בהצהרה match /databases/{database}/documents
מצוין שהכללים צריכים להתאים לכל מסד נתונים מסוג Cloud Firestore בפרויקט. כרגע לכל פרויקט יש רק מסד נתונים אחד בשם (default)
.
כללי קריאה/כתיבה בסיסיים
כללים בסיסיים מורכבים מהצהרה match
שמציינת את נתיב המסמך, ומותר להשתמש בביטוי allow
המפרט את קריאת הנתונים שצוינו:
service cloud.firestore {
match /databases/{database}/documents {
// Match any document in the 'cities' collection
match /cities/{city} {
allow read: if <condition>;
allow write: if <condition>;
}
}
}
כל הצהרות ההתאמה צריכות להפנות למסמכים, ולא לאוספים. משפט התאמה יכול להפנות למסמך ספציפי, כמו ב-match /cities/SF
, או להשתמש בתווים כלליים לחיפוש כדי להפנות לכל מסמך בנתיב שצוין, כמו ב-match /cities/{city}
.
בדוגמה שלמעלה, משפט ההתאמה משתמש בתחביר התו הכללי {city}
.
המשמעות היא שהכלל חל על כל מסמך באוסף cities
, כמו /cities/SF
או /cities/NYC
. כשמתבצעת הערכה של הביטויים allow
בהצהרת ההתאמה, המשתנה city
יהפוך לשם של המסמך של העיר, למשל SF
או NYC
.
פעולות מפורטות
במקרים מסוימים, כדאי לפרק את read
ו-write
לפעולות מפורטות יותר. לדוגמה, יכול להיות שתרצו לאכוף תנאים שונים על יצירת מסמכים מאשר על מחיקה של מסמכים. לחלופין, תוכלו לאפשר קריאה של מסמך יחיד אבל לדחות שאילתות גדולות.
אפשר לפצל כלל read
ל-get
ול-list
, ואפשר לפצל כלל write
ל-create
, ל-update
ול-delete
:
service cloud.firestore {
match /databases/{database}/documents {
// A read rule can be divided into get and list rules
match /cities/{city} {
// Applies to single document read requests
allow get: if <condition>;
// Applies to queries and collection read requests
allow list: if <condition>;
}
// A write rule can be divided into create, update, and delete rules
match /cities/{city} {
// Applies to writes to nonexistent documents
allow create: if <condition>;
// Applies to writes to existing documents
allow update: if <condition>;
// Applies to delete operations
allow delete: if <condition>;
}
}
}
נתונים היררכיים
הנתונים ב-Cloud Firestore מאורגנים באוספים של מסמכים, וכל מסמך יכול להרחיב את ההיררכיה באמצעות אוספי משנה. חשוב להבין איך כללי האבטחה פועלים יחד עם נתונים היררכיים.
נניח שכל מסמך באוסף cities
מכיל אוסף משנה של landmarks
. כללי האבטחה חלים רק על הנתיב שתואמת, כך שבקרות הגישה שהוגדרו באוסף cities
לא חלות על אוסף המשנה landmarks
. במקום זאת, כותבים כללים מפורשים כדי לשלוט בגישה לאוספים המשנה:
service cloud.firestore {
match /databases/{database}/documents {
match /cities/{city} {
allow read, write: if <condition>;
// Explicitly define rules for the 'landmarks' subcollection
match /landmarks/{landmark} {
allow read, write: if <condition>;
}
}
}
}
כשמשתמשים בהטמעת נתיב (nesting) של הצהרות match
, הנתיב של ההצהרה הפנימית של match
תמיד יחסי לנתיב של ההצהרה החיצונית של match
. לכן, כללי המדיניות הבאים זהים:
service cloud.firestore {
match /databases/{database}/documents {
match /cities/{city} {
match /landmarks/{landmark} {
allow read, write: if <condition>;
}
}
}
}
service cloud.firestore {
match /databases/{database}/documents {
match /cities/{city}/landmarks/{landmark} {
allow read, write: if <condition>;
}
}
}
תווים כלליים לחיפוש רקורסיביים
אם רוצים שהכללים יחולו על היררכיה עמוקה באופן שרירותי, צריך להשתמש בתחביר של תו כללי לחיפוש רקורסיבי, {name=**}
. לדוגמה:
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the cities collection as well as any document
// in a subcollection.
match /cities/{document=**} {
allow read, write: if <condition>;
}
}
}
כשמשתמשים בתחביר של תו כללי לחיפוש רקורסיבי, משתנה התו הכללי לחיפוש יכיל את מקטע הנתיב התואם כולו, גם אם המסמך נמצא באוסף משנה שמנוקד לעומק. לדוגמה, הכללים שמפורטים למעלה יתאימו למסמך שנמצא בכתובת /cities/SF/landmarks/coit_tower
, והערך של המשתנה document
יהיה SF/landmarks/coit_tower
.
עם זאת, חשוב לזכור שההתנהגות של תווים כלליים רפלקסיביים תלויה בגרסה של הכללים.
גרסה 1
כברירת מחדל, כללי האבטחה משתמשים בגרסה 1. בגרסה 1, תווים כלליים לחיפוש רקורסיביים תואמים לפריט נתיב אחד או יותר. הם לא תואמים לנתיב ריק, ולכן match /cities/{city}/{document=**}
תואם למסמכים באוספי המשנה אבל לא באוסף cities
, ואילו match /cities/{document=**}
תואם גם למסמכים באוסף cities
וגם באוספי המשנה.
תווים כלליים רפלקסיביים חייבים להופיע בסוף משפט התאמה.
גרסה 2
בגרסה 2 של כללי האבטחה, תווים כלליים לחיפוש רקורסיביים תואמים לאפס פריטי נתיב או יותר. match/cities/{city}/{document=**}
תואמת למסמכים בכל אוספי המשנה וגם למסמכים באוסף cities
.
כדי להביע הסכמה לגרסה 2, צריך להוסיף את הערך rules_version = '2';
בחלק העליון של כללי האבטחה:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the cities collection as well as any document
// in a subcollection.
match /cities/{city}/{document=**} {
allow read, write: if <condition>;
}
}
}
אפשר להוסיף לכל הצהרת התאמה תו כללי לחיפוש רקורסיבי אחד לכל היותר, אבל בגרסה 2 אפשר להציב את התו הכללי לחיפוש בכל מקום בהצהרת ההתאמה. לדוגמה:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the songs collection group
match /{path=**}/songs/{song} {
allow read, write: if <condition>;
}
}
}
אם אתם משתמשים בשאילתות של קבוצות אוספים, עליכם להשתמש בגרסה 2. מידע נוסף זמין במאמר אבטחת שאילתות של קבוצות אוספים.
הצהרות התאמה חופפות
יכול להיות שמסמך יתאים ליותר מטענת match
אחת. במקרים שבהם מספר ביטויים של allow
תואמים לבקשה, הגישה מותרת אם אחד מהתנאים הוא true
:
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the 'cities' collection.
match /cities/{city} {
allow read, write: if false;
}
// Matches any document in the 'cities' collection or subcollections.
match /cities/{document=**} {
allow read, write: if true;
}
}
}
בדוגמה שלמעלה, כל הקריאות והכתובות לאוסף cities
יהיו מותרות כי הכלל השני הוא תמיד true
, גם אם הכלל הראשון הוא תמיד false
.
מגבלות על כללי אבטחה
כשעובדים עם כללי אבטחה, חשוב לשים לב למגבלות הבאות:
מגבלה | פרטים |
---|---|
המספר המקסימלי של קריאות ל-exists() , ל-get() ול-getAfter() בכל בקשה |
אם חורגים מאחד מהגבולות האלה, מתקבלת הודעת שגיאה מסוג 'הרשאה נדחתה'. יכול להיות שחלק מהקריאות לגישה למסמכים יישמרו במטמון, קריאות כאלה לא נספרות במסגרת המגבלות. |
עומק הקינון המקסימלי של משפטי match |
10 |
אורך הנתיב המקסימלי, בקטעי נתיב, שמותר בקבוצה של משפטי match בתצוגת עץ |
100 |
המספר המקסימלי של משתני לכידת נתיב שמותר בקבוצה של
משפטי match בתצוגת עץ |
20 |
עומק קריאה מקסימלי של פונקציה | 20 |
המספר המקסימלי של ארגומנטים בפונקציות | 7 |
המספר המקסימלי של קישורי משתני let לכל פונקציה |
10 |
המספר המקסימלי של קריאות פונקציה חזרותיות או מחזוריות | 0 (not permitted) |
המספר המקסימלי של ביטויים שאפשר להעריך בכל בקשה | 1,000 |
גודל מקסימלי של קבוצת כללים | קבוצות הכללים חייבות לעמוד בשני מגבלות גודל:
|