Catch up on everthing we announced at this year's Firebase Summit. Learn more

שפת כללי האבטחה

כללי האבטחה של Firebase ממנפים שפות גמישות וחזקות המותאמות למגוון רחב של מורכבות ופירוט. אתה יכול להפוך את הכללים שלך לספציפיים או כלליים ככל שיהיו הגיוניים לאפליקציה שלך. כללי מסד הנתונים בזמן אמת משתמשים בתחביר שנראה כמו JavaScript במבנה JSON. ענן Firestore ו אחסון ענן כללים להשתמש בשפה המבוססת על הביטוי הנפוץ השפה (CEL) , שבונה על CEL עם match ואת allow הצהרות תמיכה שקבלה גישה מותנית.

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

בחר מוצר למידע נוסף על כלליו.

מבנה בסיסי

Cloud Firestore

כללי האבטחה של Firebase ב- Cloud Firestore ובאחסון הענן משתמשים במבנה ובתחביר הבאים:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

חשוב להבין את מושגי המפתח הבאים כאשר אתה בונה את הכללים:

  • בקשה: השיטה או השיטות להסתמך על allow בהצהרה. אלה שיטות שאתה מאפשר להפעיל. השיטות הסטנדרטיות הן: get , list , create , update , וכן delete . read ו write השיטות נוחות לאפשר גישת קריאה וכתיבה רחבה על נתיב נתון או אחסון שצוין.
  • נתיב: מיקום מסד הנתונים או אחסון, המיוצגת כנתיב URI.
  • כלל: allow אמירה, הכולל מצב המאפשר בקשה אם היא מעריכה אל נכון.

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

אחסון בענן

כללי האבטחה של Firebase ב- Cloud Firestore ובאחסון הענן משתמשים במבנה ובתחביר הבאים:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

חשוב להבין את מושגי המפתח הבאים כאשר אתה בונה את הכללים:

  • בקשה: השיטה או השיטות להסתמך על allow בהצהרה. אלה שיטות שאתה מאפשר להפעיל. השיטות הסטנדרטיות הן: get , list , create , update , וכן delete . read ו write השיטות נוחות לאפשר גישת קריאה וכתיבה רחבה על נתיב נתון או אחסון שצוין.
  • נתיב: מיקום מסד הנתונים או אחסון, המיוצגת כנתיב URI.
  • כלל: allow אמירה, הכולל מצב המאפשר בקשה אם היא מעריכה אל נכון.

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

מסד נתונים בזמן אמת

במסד הנתונים בזמן אמת, כללי האבטחה של Firebase מורכבים מביטויים דמויי JavaScript הכלולים במסמך JSON.

הם משתמשים בתחביר הבא:

{
  "rules": {
    "<<path>>": {
    // Allow the request if the condition for each method is true.
      ".read": <<condition>>,
      ".write": <<condition>>,
      ".validate": <<condition>>
    }
  }
}

ישנם שלושה יסודות בסיסיים בחוק:

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

מבני חוק

Cloud Firestore

המרכיבים הבסיסיים של כלל ב- Cloud Firestore וב- Cloud Storage הם כדלקמן:

  • service הכרזה: הכרזה על מוצר Firebase הכללים החלים על.
  • match בלוק: מגדיר נתיב בים הנתונים או אחסון הכללים החלים על.
  • allow הצהרה: מספקת תנאי גישת מתן, נבדלים בשיטות. השיטות הנתמכות כוללות: get , list , create , update , delete , ואת שיטות נוחות read ו write .
  • אופציונאלי function הצהרות: ספקו את היכולת לשלב ועוטפי תנאים לשימוש ברחבי כללים מרובים.

service מכיל אחד או יותר match בלוקים עם allow דוחות המספקים תנאים למתן גישה לבקשות. request ו resource המשתנה זמינים לשימוש בתנאי כלל. השפה כללי אבטחת Firebase תומך גם function הצהרות.

גרסת תחביר

syntax המשפט מציין את גרסת שפת כללי Firebase נהגה לכתוב את המקור. הגרסה האחרונה של השפה היא v2 .

rules_version = '2';
service cloud.firestore {
...
}

אם אין rules_version אמירה מסופקת, הכללים שלך יוערכו באמצעות v1 המנוע.

שֵׁרוּת

service מגדיר ההכרזה איזה מוצר Firebase, או שירות, הכללים שלך חלים. אתה יכול לכלול רק אחד service ההכרזה לכל קובץ המקור.

Cloud Firestore

service cloud.firestore {
 // Your 'match' blocks with their corresponding 'allow' statements and
 // optional 'function' declarations are contained here
}

אחסון בענן

service firebase.storage {
  // Your 'match' blocks with their corresponding 'allow' statements and
  // optional 'function' declarations are contained here
}

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

התאמה

match לחסום מצהיר על path דפוס זה מתאים נגד הנתיב עבור הפעולה המבוקשת (הנכנס request.path ). הגוף של match חייב להיות אחד או יותר מקוננות match בלוקים, allow דוח, או function הצהרות. השביל ב מקוננות match בלוקים הוא יחסים לנתיב ב הורה match הבלוק.

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

משחקים נגד path דפוס עשוי להיות חלקי או מלא:

  • גפרורים חלקיים: path דפוס התאמה-קידומת של request.path .
  • גפרורים הושלם: path דפוס התואם את כולו request.path .

כאשר נוצרים התאמה מלאה נעשית הכללים בתוך הבלוק מוערכים. כאשר נוצרים התאמה חלקית הוא עשה את מקוננות match הכללים נבדקים כדי לראות אם מקונן path ישלים את המשחק.

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

// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
  // Partial match.
  match /example/{singleSegment} {   // `singleSegment` == 'hello'
    allow write;                     // Write rule not evaluated.
    // Complete match.
    match /nested/path {             // `singleSegment` visible in scope.
      allow read;                    // Read rule is evaluated.
    }
  }
  // Complete match.
  match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
    allow read;                      // Read rule is evaluated.
  }
}

כמו בדוגמא לעיל ניתן ללמוד כי path הכרזות תומכות המשתנים הבאים:

  • כללי Single-פלח: משתנה כללי מוכרז בנתיב ידי לפפה משתנה ב סוגריים מסולסלים: {variable} . משתנה זה הוא נגיש בתוך match האמירה כמו string .
  • כלליים רקורסיבית: The רקורסיבית, או-קטע רב, גפרורים כלליים מספר מקטעי נתיב או מתחת נתיב. תו כללי זה תואם את כל הנתיבים מתחת למיקום שהגדרת אותו. אתה יכול להצהיר על ידי ההוספה =** המחרוזת בסוף משתנה הקטע שלך: {variable=**} . משתנה זה הוא נגיש בתוך match האמירה כמו path אובייקט.

להתיר

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

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

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

service firebase.storage {
  // Allow the requestor to read or delete any resource on a path under the
  // user directory.
  match /users/{userId}/{anyUserFile=**} {
    allow read, delete: if request.auth != null && request.auth.uid == userId;
  }

  // Allow the requestor to create or update their own images.
  // When 'request.method' == 'delete' this rule and the one matching
  // any path under the user directory would both match and the `delete`
  // would be permitted.

  match /users/{userId}/images/{imageId} {
    // Whether to permit the request depends on the logical OR of all
    // matched rules. This means that even if this rule did not explicitly
    // allow the 'delete' the earlier rule would have.
    allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
  }
}

שיטה

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

שיטה סוג הבקשה
שיטות נוחות
read כל סוג של בקשת קריאה
write כל סוג של בקשת כתיבה
שיטות סטנדרטיות
get קרא בקשות למסמכים או קבצים בודדים
list קרא בקשות לשאילתות ואוספים
create כתוב מסמכים או קבצים חדשים
update כתוב למסמכי מסד נתונים קיימים או עדכן מטא נתונים של קובץ
delete מחק נתונים

אתה לא יכול לקרוא בשיטות חפיפה באותו match לחסום או שיטות כתיבה סותרות באותו path הכרזה.

לדוגמה, הכללים הבאים ייכשלו:

service bad.example {
  match /rules/with/overlapping/methods {
    // This rule allows reads to all authenticated users
    allow read: if request.auth != null;

    match another/subpath {
      // This secondary, more specific read rule causes an error
      allow get: if request.auth != null && request.auth.uid == "me";
      // Overlapping write methods in the same path cause an error as well
      allow write: if request.auth != null;
      allow create: if request.auth != null && request.auth.uid == "me";
    }
  }
}

פוּנקצִיָה

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

  • פונקציות יכולות להכיל אחת בלבד return בהצהרה. הם אינם יכולים להכיל היגיון נוסף. לדוגמה, הם אינם יכולים לבצע לולאות או להתקשר לשירותים חיצוניים.
  • פונקציות יכולות לגשת אוטומטית לפונקציות ולמשתנים מההיקף שבו הן מוגדרות. לדוגמא, פונקציה המוגדרת בתוך service cloud.firestore ההיקף לו גישה resource משתנה מובנה פונקציות כגון get() ו exists() .
  • פונקציות עשויות לכנות פונקציות אחרות אך אינן יכולות לחזור על עצמן. העומק הכולל של מחסנית השיחות מוגבל ל -20.
  • בגרסת כללי v2 , פונקציות יכולות להגדיר משתנות באמצעות let מילות המפתח. פונקציות יכולות להכיל עד 10 כריכות אישור, אך חייבות להסתיים בהצהרת החזרה.

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

service cloud.firestore {
  match /databases/{database}/documents {
    // True if the user is signed in or the requested data is 'public'
    function signedInOrPublic() {
      return request.auth.uid != null || resource.data.visibility == 'public';
    }

    match /cities/{city} {
      allow read, write: if signedInOrPublic();
    }

    match /users/{user} {
      allow read, write: if signedInOrPublic();
    }
  }
}

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

function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
  return isAuthor || isAdmin;
}

שים לב איך isAdmin המשימה אוכפת בדיקת אוסף המנהלים. לקבלת הערכה עצלנית ללא צורך חיפושי מיותרת, לנצל את הטבע-להיגרם הקצר של && (AND) ו || (OR) השוואות לקרוא לפונקציה השנייה רק אם isAuthor מוצג להיות אמיתי (עבור && השוואות) או שקר (עבור || השוואות).

function isAdmin(userId) {
  return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  // `||` is short-circuiting; isAdmin called only if isAuthor == false.
  return isAuthor || isAdmin(userId);
}

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

אחסון בענן

המרכיבים הבסיסיים של כלל ב- Cloud Firestore וב- Cloud Storage הם כדלקמן:

  • service הכרזה: הכרזה על מוצר Firebase הכללים החלים על.
  • match בלוק: מגדיר נתיב בים הנתונים או אחסון הכללים החלים על.
  • allow הצהרה: מספקת תנאי גישת מתן, נבדלים בשיטות. השיטות הנתמכות כוללות: get , list , create , update , delete , ואת שיטות נוחות read ו write .
  • אופציונלי function הצהרות: ספקו את היכולת לשלב ועוטפי תנאים לשימוש ברחבי כללים מרובים.

service מכיל אחד או יותר match בלוקים עם allow דוחות המספקים תנאים למתן גישה לבקשות. request ו resource המשתנה זמינים לשימוש בתנאי כלל. השפה כללי אבטחת Firebase תומך גם function הצהרות.

גרסת תחביר

syntax המשפט מציין את גרסת שפת כללי Firebase נהגה לכתוב את המקור. הגרסה האחרונה של השפה היא v2 .

rules_version = '2';
service cloud.firestore {
...
}

אם אין rules_version אמירה מסופקת, הכללים שלך יוערכו באמצעות v1 המנוע.

שֵׁרוּת

service מגדיר ההכרזה איזה מוצר Firebase, או שירות, הכללים שלך חלים. אתה יכול לכלול רק אחד service ההכרזה לכל קובץ המקור.

Cloud Firestore

service cloud.firestore {
 // Your 'match' blocks with their corresponding 'allow' statements and
 // optional 'function' declarations are contained here
}

אחסון בענן

service firebase.storage {
  // Your 'match' blocks with their corresponding 'allow' statements and
  // optional 'function' declarations are contained here
}

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

התאמה

match לחסום מצהיר על path דפוס זה מתאים נגד הנתיב עבור הפעולה המבוקשת (הנכנס request.path ). הגוף של match חייב להיות אחד או יותר מקוננות match בלוקים, allow דוח, או function הצהרות. השביל ב מקוננות match בלוקים הוא יחסים לנתיב ב הורה match הבלוק.

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

משחקים נגד path דפוס עשוי להיות חלקי או מלא:

  • גפרורים חלקיים: path דפוס התאמה-קידומת של request.path .
  • גפרורים הושלם: path דפוס התואם את כולו request.path .

כאשר נוצרים התאמה מלאה נעשית הכללים בתוך הבלוק מוערכים. כאשר נוצרים התאמה חלקית הוא עשה את מקוננות match הכללים נבדקים כדי לראות אם מקונן path ישלים את המשחק.

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

// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
  // Partial match.
  match /example/{singleSegment} {   // `singleSegment` == 'hello'
    allow write;                     // Write rule not evaluated.
    // Complete match.
    match /nested/path {             // `singleSegment` visible in scope.
      allow read;                    // Read rule is evaluated.
    }
  }
  // Complete match.
  match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
    allow read;                      // Read rule is evaluated.
  }
}

כמו בדוגמא לעיל ניתן ללמוד כי path הכרזות תומכות המשתנים הבאים:

  • כללי Single-פלח: משתנה כללי מוכרז בנתיב ידי לפפה משתנה ב סוגריים מסולסלים: {variable} . משתנה זה הוא נגיש בתוך match האמירה כמו string .
  • כלליים רקורסיבית: The רקורסיבית, או-קטע רב, גפרורים כלליים מספר מקטעי נתיב או מתחת נתיב. תו כללי זה תואם את כל הנתיבים מתחת למיקום שהגדרת אותו. אתה יכול להצהיר על ידי ההוספה =** המחרוזת בסוף משתנה הקטע שלך: {variable=**} . משתנה זה הוא נגיש בתוך match האמירה כמו path אובייקט.

להתיר

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

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

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

service firebase.storage {
  // Allow the requestor to read or delete any resource on a path under the
  // user directory.
  match /users/{userId}/{anyUserFile=**} {
    allow read, delete: if request.auth != null && request.auth.uid == userId;
  }

  // Allow the requestor to create or update their own images.
  // When 'request.method' == 'delete' this rule and the one matching
  // any path under the user directory would both match and the `delete`
  // would be permitted.

  match /users/{userId}/images/{imageId} {
    // Whether to permit the request depends on the logical OR of all
    // matched rules. This means that even if this rule did not explicitly
    // allow the 'delete' the earlier rule would have.
    allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
  }
}

שיטה

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

שיטה סוג הבקשה
שיטות נוחות
read כל סוג של בקשת קריאה
write כל סוג של בקשת כתיבה
שיטות סטנדרטיות
get קרא בקשות למסמכים או קבצים בודדים
list קרא בקשות לשאילתות ואוספים
create כתוב מסמכים או קבצים חדשים
update כתוב למסמכי מסד נתונים קיימים או עדכן מטא נתונים של קובץ
delete מחק נתונים

אתה לא יכול לקרוא בשיטות חפיפה באותו match לחסום או שיטות כתיבה סותרות באותו path הכרזה.

לדוגמה, הכללים הבאים ייכשלו:

service bad.example {
  match /rules/with/overlapping/methods {
    // This rule allows reads to all authenticated users
    allow read: if request.auth != null;

    match another/subpath {
      // This secondary, more specific read rule causes an error
      allow get: if request.auth != null && request.auth.uid == "me";
      // Overlapping write methods in the same path cause an error as well
      allow write: if request.auth != null;
      allow create: if request.auth != null && request.auth.uid == "me";
    }
  }
}

פוּנקצִיָה

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

  • פונקציות יכולות להכיל אחת בלבד return בהצהרה. הם אינם יכולים להכיל היגיון נוסף. לדוגמה, הם אינם יכולים לבצע לולאות או להתקשר לשירותים חיצוניים.
  • פונקציות יכולות לגשת אוטומטית לפונקציות ולמשתנים מההיקף שבו הן מוגדרות. לדוגמא, פונקציה המוגדרת בתוך service cloud.firestore ההיקף לו גישה resource משתנה מובנה פונקציות כגון get() ו exists() .
  • פונקציות עשויות לכנות פונקציות אחרות אך אינן יכולות לחזור על עצמן. העומק הכולל של ערימת שיחות מוגבל ל -20.
  • בגרסת כללי v2 , פונקציות יכולות להגדיר משתנות באמצעות let מילות המפתח. פונקציות יכולות להכיל עד 10 כריכות מאפשרות, אך חייבות להסתיים בהצהרת החזרה.

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

service cloud.firestore {
  match /databases/{database}/documents {
    // True if the user is signed in or the requested data is 'public'
    function signedInOrPublic() {
      return request.auth.uid != null || resource.data.visibility == 'public';
    }

    match /cities/{city} {
      allow read, write: if signedInOrPublic();
    }

    match /users/{user} {
      allow read, write: if signedInOrPublic();
    }
  }
}

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

function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
  return isAuthor || isAdmin;
}

שים לב איך isAdmin המשימה אוכפת בדיקת אוסף המנהלים. לקבלת הערכה עצלנית ללא צורך חיפושי מיותרת, לנצל את הטבע-להיגרם הקצר של && (AND) ו || (OR) השוואות לקרוא לפונקציה השנייה רק אם isAuthor מוצג להיות אמיתי (עבור && השוואות) או שקר (עבור || השוואות).

function isAdmin(userId) {
  return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  // `||` is short-circuiting; isAdmin called only if isAuthor == false.
  return isAuthor || isAdmin(userId);
}

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

מסד נתונים בזמן אמת

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

מיקום מסד הנתונים

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

  {
    "messages": {
      "message0": {
        "content": "Hello",
        "timestamp": 1405704370369
      },
      "message1": {
        "content": "Goodbye",
        "timestamp": 1405704395231
      },
      ...
    }
  }

החוקים שלך צריכים לשקף את המבנה הזה. לדוגמה:

  {
    "rules": {
      "messages": {
        "$message": {
          // only messages from the last ten minutes can be read
          ".read": "data.child('timestamp').val() > (now - 600000)",

          // new messages must have a string content and a number timestamp
          ".validate": "newData.hasChildren(['content', 'timestamp']) &&
                        newData.child('content').isString() &&
                        newData.child('timestamp').isNumber()"
        }
      }
    }
  }

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

  {
    "rules": {
      "rooms": {
        // This rule applies to any child of /rooms/, the key for each room id
        // is stored inside $room_id variable for reference
        "$room_id": {
          "topic": {
            // The room's topic can be changed if the room id has "public" in it
            ".write": "$room_id.contains('public')"
          }
        }
      }
    }
  }

אתה יכול גם להשתמש $variable במקביל שמות נתיב קבוע.

  {
    "rules": {
      "widget": {
        // a widget can have a title or color attribute
        "title": { ".validate": true },
        "color": { ".validate": true },

        // but no other child paths are allowed
        // in this case, $other means any key excluding "title" and "color"
        "$other": { ".validate": false }
      }
    }
  }

שיטה

במאגר זמן אמת, ישנם שלושה סוגים של כללים. שני סוגים אלה השולטים - read ו write - חלים על שיטת בקשה נכנסת. validate סוג השלטון אוכף מבני נתונים ומאמת את הפורמט ותוכן של נתונים. כללים פועלים .validate כללים לאחר אימות כי .write הכלל המקנה גישה.

סוגי חוק
.לקרוא מתאר אם ומתי משתמשים רשאים לקרוא נתונים.
.לִכתוֹב מתאר אם וכאשר מותר לכתוב נתונים.
.לְאַמֵת מגדיר כיצד ייראה ערך בפורמט נכון, האם יש לו תכונות צאצא וסוג הנתונים.

כברירת מחדל, אם אין כלל המאפשר זאת, הגישה בנתיב נדחית.

תנאי בנייה

Cloud Firestore

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

request משתנה

request משתנית כולל את השדות הבאים ומידע מתאים:

request.auth

אסימון אינטרנט JSON (JWT) המכיל אישורי אימות מאימות Firebase. auth אסימון מכיל סט של טענות סטנדרטיות וכול הטענות מותאמות אישית שתוכל ליצור באמצעות Firebase אימות. למידע נוסף על Firebase אבטחת כללי אימות .

request.method

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

request.params

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

request.path

request.path הוא הנתיב עבור יעד resource . הדרך היא יחסית לשירות. מקטעי נתיב המכילים תווים שאינם url בטוח כגון / הם בקידוד URL.

resource משתנה

resource הוא הערך הנוכחי במסגרת השירות המיוצג כמפה של זוגות מפתח-ערך. הפנית resource בתוך מצב תגרום לכל היותר אחד לקרוא את הערך מהשירות. חיפוש זה ייחשב לכל מכסה הקשורה לשירות עבור המשאב. לקבלת get בקשות, resource יספור רק במסגרת מכסה על להכחיש.

עדיפות למפעילים ולמפעילים

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

בהתחשב ביטויים שרירותיים ו a b , שדה f , ואינדקס i .

מַפעִיל תיאור אסוציאטיביות
a[i] a() af אינדקס, שיחה, גישה לשדה משמאל לימין
!a -a שלילה מאוחדת מימין לשמאל
a/ba%ba*b אופרטורים כפליים משמאל לימין
a+b ab אופרטורים תוספים משמאל לימין
a>ba>=ba מפעילים יחסיים משמאל לימין
a in b קיום ברשימה או במפה משמאל לימין
a is type השוואת סוג, שם type יכול להיות bool, int, לצוף, מספר, מחרוזת, רשימה, המפה, חותמת, משך, נתיב או נ"צ משמאל לימין
a==ba!=b מפעילי השוואה משמאל לימין
a && b מותנה וגם משמאל לימין
a || b מותנה או משמאל לימין
a ? true_value : false_value ביטוי שלישי משמאל לימין

אחסון בענן

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

request משתנה

request משתנית כולל את השדות הבאים ומידע מתאים:

request.auth

אסימון אינטרנט JSON (JWT) המכיל אישורי אימות מאימות Firebase. auth אסימון מכיל סט של טענות סטנדרטיות וכול הטענות מותאמות אישית שתוכל ליצור באמצעות Firebase אימות. למידע נוסף על Firebase אבטחת כללי אימות .

request.method

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

request.params

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

request.path

request.path הוא הנתיב עבור יעד resource . הדרך היא יחסית לשירות. מקטעי נתיב המכילים תווים שאינם url בטוח כגון / הם בקידוד URL.

resource משתנה

resource הוא הערך הנוכחי במסגרת השירות המיוצג כמפה של זוגות מפתח-ערך. הפנית resource בתוך מצב תגרום לכל היותר אחד לקרוא את הערך מהשירות. חיפוש זה ייחשב לכל מכסה הקשורה לשירות עבור המשאב. לקבלת get בקשות, resource יספור רק במסגרת מכסה על להכחיש.

עדיפות למפעילים ולמפעילים

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

בהתחשב ביטויים שרירותיים ו a b , שדה f , ואינדקס i .

מַפעִיל תיאור אסוציאטיביות
a[i] a() af אינדקס, שיחה, גישה לשדה משמאל לימין
!a -a שלילה מאוחדת מימין לשמאל
a/ba%ba*b אופרטורים כפליים משמאל לימין
a+b ab אופרטורים תוספים משמאל לימין
a>ba>=ba מפעילים יחסיים משמאל לימין
a in b קיום ברשימה או במפה משמאל לימין
a is type השוואת סוג, שם type יכול להיות bool, int, לצוף, מספר, מחרוזת, רשימה, המפה, חותמת, משך, נתיב או נ"צ משמאל לימין
a==ba!=b מפעילי השוואה משמאל לימין
a && b מותנה וגם משמאל לימין
a || b מותנה או משמאל לימין
a ? true_value : false_value ביטוי שלישי משמאל לימין

מסד נתונים בזמן אמת

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

משתנים מוגדרים מראש

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

משתנים מוגדרים מראש
עַכשָׁיו הזמן הנוכחי באלפיות השנייה מאז עידן לינוקס. זה עובד טוב במיוחד לאימות חותמות זמן שנוצרו עם firebase.database.ServerValue.TIMESTAMP של SDK.
שורש RuleDataSnapshot המייצג את הנתיב שורש במסד הנתונים Firebase כפי שהיא קיימת לפני הניתוח ניסו.
מידע חדש RuleDataSnapshot המייצג את הנתונים כפי שהוא היה קיים לאחר הניתוח ניסו. הוא כולל את הנתונים החדשים שנכתבים ואת הנתונים הקיימים.
נתונים RuleDataSnapshot המייצג את הנתונים כפי שהיה קיים לפני הניתוח ניסו.
משתנים $ נתיב תווים כלליים המשמש לייצוג מזהים ומפתחות ילדים דינמיים.
aut מייצג מטען אסימון של משתמש מאומת.

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

{
  "rules": {
    "foo": {
      // /foo is readable by the world
      ".read": true,

      // /foo is writable by the world
      ".write": true,

      // data written to /foo must be a string less than 100 characters
      ".validate": "newData.isString() && newData.val().length < 100"
    }
  }
}

כללים מבוססי נתונים

ניתן להשתמש בכל הנתונים במסד הנתונים שלך בכללים שלך. השימוש המשתנים מוגדרים מראש root , data , ו newData , אתה יכול לגשת לכל נתיב כפי שהוא היה קיים לפני או אחרי אירוע כתיבה.

קח לדוגמה זו, המאפשרת פעולות כתיבה עוד משווי /allow_writes/ צומת הוא true , צומת האב אין readOnly סט דגל, ויש ילד בשם foo בנתון החדש שנכתב:

".write": "root.child('allow_writes').val() === true &&
          !data.parent().child('readOnly').exists() &&
          newData.child('foo').exists()"

כללים מבוססי שאילתה

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

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

"baskets": {
  ".read": "auth.uid != null &&
            query.orderByChild == 'owner' &&
            query.equalTo == auth.uid" // restrict basket access to owner of basket
}

השאילתה הבאה, הכוללת את פרמטרי השאילתה בכלל, תצליח:

db.ref("baskets").orderByChild("owner")
                 .equalTo(auth.currentUser.uid)
                 .on("value", cb)                 // Would succeed

עם זאת, שאילתות שאינן כוללות את הפרמטרים הכלל תיכשל עם PermissionDenied שגיאה:

db.ref("baskets").on("value", cb)                 // Would fail with PermissionDenied

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

לדוגמה, הכלל הבא מגביל את גישת הקריאה ל -1000 התוצאות הראשונות של שאילתה בלבד, לפי סדר העדיפויות:

messages: {
  ".read": "query.orderByKey &&
            query.limitToFirst <= 1000"
}

// Example queries:

db.ref("messages").on("value", cb)                // Would fail with PermissionDenied

db.ref("messages").limitToFirst(1000)
                  .on("value", cb)                // Would succeed (default order by key)

להלן query. ביטויים זמינים בכללי מסד הנתונים בזמן אמת.

ביטויי חוק המבוססים על שאילתה
ביטוי סוּג תיאור
query.orderByKey
query.orderByPriority
query.orderByValue
בוליאני נכון לשאילתות המוזמנות לפי מפתח, עדיפות או ערך. שקר אחרת.
query.orderByChild חוּט
ריק
השתמש במחרוזת כדי לייצג את הנתיב היחסי לצומת ילדים. לדוגמה, query.orderByChild == "address/zip" . אם השאילתה אינה מסודרת על ידי צומת ילדים, ערך זה הוא אפס.
query.startAt
query.endAt
query.equalTo
חוּט
מספר
בוליאני
ריק
אחזור גבולות שאילתת הביצוע, או מחזיר null אם אין קבוצה מוגבלת.
query.limitToFirst
query.limitToLast
מספר
ריק
אחזור המגבלה על שאילתת הביצוע, או מחזיר null אם אין הגבלה.

מפעילים

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

יצירת תנאים

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

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