הוראות איך לאבטח קבצים

Cloud Storage for Firebase מספק מודל אבטחה מבוסס-נתיב הצהרתי שנקרא Firebase Security Rules עבור Cloud Storage, מה שמאפשר לך לאבטח את הקבצים.

הסבר על כללים

Firebase Security Rules עבור Cloud Storage משמשים כדי לקבוע מי קרא וכתב גישה לקבצים המאוחסנים ב-Cloud Storage וגם את אופן הפעולה של הקבצים המובנה והמטא-נתונים שהם כוללים. הסוג הבסיסי של כלל הוא כלל allow, שמאפשר בקשות read ו-write אם צוין תנאי אופציונלי, לדוגמה:

// If no condition is specified, the rule evaluates to true
allow read;

// Rules can optionally specify a condition
allow write: if <condition>;

// Rules can also specify multiple request methods
allow read, write: if <condition>;

נתיבים תואמים

Cloud Storage Security Rules match נתיבי הקבצים שמשמשים לגישה לקבצים ב-Cloud Storage. כללים יכולים match נתיבים מדויקים או נתיבים עם תווים כלליים לחיפוש, וגם אפשר גם להציב כללים בתצוגת עץ. אם אין כלל התאמה שמאפשר שיטת בקשה, או אם התנאי מקבל את הערך false, הבקשה נדחית.

התאמות מדויקות

// Exact match for "images/profilePhoto.png"
match /images/profilePhoto.png {
  allow write: if <condition>;
}

// Exact match for "images/croppedProfilePhoto.png"
match /images/croppedProfilePhoto.png {
  allow write: if <other_condition>;
}

גפרורים מקוננים

// Partial match for files that start with "images"
match /images {
  // Exact match for "images/profilePhoto.png"
  match /profilePhoto.png {
    allow write: if <condition>;
  }

  // Exact match for "images/croppedProfilePhoto.png"
  match /croppedProfilePhoto.png {
    allow write: if <other_condition>;
  }
}

התאמות של תווים כלליים לחיפוש

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

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

// Partial match for files that start with "images"
match /images {
  // Exact match for "images/*"
  // e.g. images/profilePhoto.png is matched
  match /{imageId} {
    // This rule only matches a single path segment (*)
    // imageId is a string that contains the specific segment matched
    allow read: if <condition>;
  }

  // Exact match for "images/**"
  // e.g. images/users/user:12345/profilePhoto.png is matched
  // images/profilePhoto.png is also matched!
  match /{allImages=**} {
    // This rule matches one or more path segments (**)
    // allImages is a path that contains all segments matched
    allow read: if <other_condition>;
  }
}

אם כמה כללים תואמים לקובץ, התוצאה היא OR של התוצאה של כל הערכות הכללים. כלומר, אם כלל כלשהו שתואם לקובץ מקבל ערך true, הערך של הפרמטר התוצאה היא true.

בכללים שלמעלה, הקובץ "images/profilePhoto.png" ניתן לקרוא אם אחד מהם הערך של condition או other_condition הוא True, אבל הקובץ "images/users/user:12345/profilePhoto.png" כפוף לתוצאה של other_condition.

אפשר להפנות למשתנה תו כללי לחיפוש מתוך ההרשאה של שם הקובץ או הנתיב של הספק match:

// Another way to restrict the name of a file
match /images/{imageId} {
  allow read: if imageId == "profilePhoto.png";
}

Cloud Storage Security Rules לא מדורגים, והכללים נבדקים רק כאשר נתיב הבקשה תואם לנתיב שצוינו בכללים.

בקשה להערכה

העלאות, הורדות, שינויים במטא-נתונים ומחיקות מוערכות באמצעות נשלח סכום של request אל Cloud Storage. המשתנה request מכיל את הערך נתיב הקובץ שבו הבקשה מתבצעת, השעה שבה הבקשה שהתקבלו, והערך resource החדש אם הבקשה היא כתיבה. כותרות HTTP ומצב האימות כלולים גם הם.

האובייקט request מכיל גם את המזהה הייחודי של המשתמש וגם את המטען הייעודי (payload) מסוג Firebase Authentication באובייקט request.auth, שיהיה שמוסבר בפירוט בקטע אבטחה מבוססת-משתמשים של המסמכים.

רשימה מלאה של המאפיינים באובייקט request זמינה בהמשך:

נכס סוג תיאור
auth מפה<string, string> כשמשתמש מחובר, מספק uid, המזהה הייחודי של המשתמש, וגם token, מפה של Firebase Authentication הצהרות JWT. אחרת, null
params מפה<string, string> מפה שמכילה את הפרמטרים של השאילתה של הבקשה.
path נתיב path שמייצג את הנתיב שבו הבקשה נמצאת הביצועים של.
resource מפה<string, string> ערך המשאב החדש, שנמצא רק בבקשות write.
time חותמת זמן חותמת זמן שמייצגת את הזמן שבו מתבצעת בדיקת הבקשה בשרת.

הערכת משאבים

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

Firebase Security Rules עבור Cloud Storage מספק מטא-נתונים של קבצים בresource שמכיל צמדי מפתח/ערך של המטא-נתונים שמופיעים אובייקט Cloud Storage. אפשר לבדוק את המאפיינים האלה ב-read או בקשות write כדי להבטיח את תקינות הנתונים.

בבקשות write (כמו העלאות, עדכוני מטא-נתונים ומחיקות), ב- בנוסף לאובייקט resource, שמכיל מטא-נתונים של הקובץ שקיים כרגע בנתיב הבקשה, אפשר גם להשתמש אובייקט request.resource, שמכיל קבוצת משנה של המטא-נתונים של הקובץ כתיבה, אם הכתיבה מותרת. אפשר להשתמש בשני הערכים האלה כדי לוודא את תקינות הנתונים או לאכוף אילוצים באפליקציה, כמו סוג הקובץ או הגודל שלו.

רשימה מלאה של המאפיינים באובייקט resource זמינה בהמשך:

נכס סוג תיאור
name מחרוזת השם המלא של האובייקט
bucket מחרוזת שם הקטגוריה שבה נמצא האובייקט הזה.
generation int GCS של האובייקט.
metageneration int GCS את המטא-גנרציה של האובייקט.
size int גודל האובייקט בבייטים.
timeCreated חותמת זמן חותמת זמן שמייצגת את השעה שבה האובייקט נוצר.
updated חותמת זמן חותמת זמן שמייצגת את הזמן שבו אובייקט עודכן לאחרונה.
md5Hash מחרוזת גיבוב MD5 של האובייקט.
crc32c מחרוזת גיבוב CRC32C של האובייקט.
etag מחרוזת ה-etag שמשויך לאובייקט הזה.
contentDisposition מחרוזת צורת התוכן שמשויכת לאובייקט הזה.
contentEncoding מחרוזת קידוד התוכן שמשויך לאובייקט הזה.
contentLanguage מחרוזת שפת התוכן שמשויכת לאובייקט הזה.
contentType מחרוזת סוג התוכן שמשויך לאובייקט הזה.
metadata מפה<string, string> צמדי מפתח/ערך של מטא-נתונים מותאמים אישית נוספים שהמפתח ציין.

request.resource מכיל את כל אלה, מלבד generation, metageneration, etag, timeCreated וגם updated.

דוגמה מלאה

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

service firebase.storage {
 match /b/{bucket}/o {
   match /images {
     // Cascade read to any image type at any path
     match /{allImages=**} {
       allow read;
     }

     // Allow write files to the path "images/*", subject to the constraints:
     // 1) File is less than 5MB
     // 2) Content type is an image
     // 3) Uploaded content type matches existing content type (if it exists)
     // 4) File name (stored in imageId wildcard variable) is less than 32 characters
     match /{imageId} {
       allow write: if request.resource.size < 5 * 1024 * 1024
                    && request.resource.contentType.matches('image/.*')
                    && (resource == null || request.resource.contentType == resource.contentType)
                    && imageId.size() < 32
     }
   }
 }
}

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