כללי אבטחה בסיסיים

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

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

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

כללי ברירת מחדל: מצב נעול

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

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

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

{
  "rules": {
    ".read": false,
    ".write": false
  }
}

אחסון בענן

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

כללי פיתוח-סביבה

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

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

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

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

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

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

{
  "rules": {
    ".read": "auth.uid !== null",
    ".write": "auth.uid !== null"
  }
}

אחסון בענן

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}

חוקים מוכנים להפקה

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

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

גישה לבעלי תוכן בלבד

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

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

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

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

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow only authenticated content owners access
    match /some_collection/{userId}/{documents=**} {
      allow read, write: if request.auth != null && request.auth.uid == userId
    }
  }
}

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

{
  "rules": {
    "some_path": {
      "$uid": {
        // Allow only authenticated content owners access to their data
        ".read": "auth !== null && auth.uid === $uid",
        ".write": "auth !== null && auth.uid === $uid"
      }
    }
  }
}

אחסון בענן

// Grants a user access to a node matching their user ID
service firebase.storage {
  match /b/{bucket}/o {
    // Files look like: "user/<UID>/path/to/file.txt"
    match /user/{userId}/{allPaths=**} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
  }
}

גישה ציבורית ופרטית מעורבת

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

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

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

כדי להגדיר כלל זה: צור כלל המאפשר גישת קריאה לכל המשתמשים (או לכל המשתמשים המאומתים), ומאשר שהמשתמש כותב הנתונים הוא הבעלים.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow public read access, but only content owners can write
    match /some_collection/{document} {
      allow read: if true
      allow create: if request.auth.uid == request.resource.data.author_uid;
      allow update, delete: if request.auth.uid == resource.data.author_uid;
    }
  }
}

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

{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data

  "rules": {
    "some_path": {
      "$uid": {
        ".read": true,
        // or ".read": "auth.uid !== null" for only authenticated users
        ".write": "auth.uid === $uid"
      }
    }
  }
}

אחסון בענן

service firebase.storage {
  match /b/{bucket}/o {
    // Files look like: "user/<UID>/path/to/file.txt"
    match /user/{userId}/{allPaths=**} {
      allow read;
      allow write: if request.auth.uid == userId;
    }
  }
}

גישה מבוססת תכונות ותפקידים

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

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

כשהכלל הזה לא עובד: במסד נתונים בזמן אמת ובאחסון בענן, הכללים שלך לא יכולים למנף את שיטת get() שכללי Cloud Firestore יכולים לשלב. כתוצאה מכך, עליך לבנות את מטא נתונים של מסד הנתונים או הקובץ כדי לשקף את התכונות שבהן אתה משתמש בכללים שלך.

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

אתה יכול גם להגדיר תביעות מותאמות אישית באימות ולאחר מכן לאחזר את המידע הזה מהמשתנה auth.token בכל כללי האבטחה של Firebase.

תכונות ותפקידים המוגדרים בנתונים

כללים אלה פועלים רק ב-Cloud Firestore ובמסד נתונים בזמן אמת.

Cloud Firestore

זכור שבכל פעם שהכללים שלך כוללים קריאה, כמו הכללים שלהלן, תחויב עבור פעולת קריאה ב-Cloud Firestore.

service cloud.firestore {
  match /databases/{database}/documents {
    // For attribute-based access control, Check a boolean `admin` attribute
    allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
    allow read: true;

    // Alterntatively, for role-based access, assign specific roles to users
    match /some_collection/{document} {
     allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader"
     allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer"
   }
  }
}

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

{
  "rules": {
    "some_path": {
      "${subpath}": {
        //
        ".write": "root.child('users').child(auth.uid).child('role').val() === 'admin'",
        ".read": true
      }
    }
  }
}

מאפיינים ותפקידים של תביעה בהתאמה אישית

כדי ליישם כללים אלה, הגדר תביעות מותאמות אישית באימות Firebase ולאחר מכן נצל את התביעות בכללים שלך.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // For attribute-based access control, check for an admin claim
    allow write: if request.auth.token.admin == true;
    allow read: true;

    // Alterntatively, for role-based access, assign specific roles to users
    match /some_collection/{document} {
     allow read: if request.auth.token.reader == "true";
     allow write: if request.auth.token.writer == "true";
   }
  }
}

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

{
  "rules": {
    "some_path": {
      "$uid": {
        // Create a custom claim for each role or group
        // you want to leverage
        ".write": "auth.uid !== null && auth.token.writer === true",
        ".read": "auth.uid !== null && auth.token.reader === true"
      }
    }
  }
}

אחסון בענן

service firebase.storage {
  // Allow reads if the group ID in your token matches the file metadata's `owner` property
  // Allow writes if the group ID is in the user's custom token
  match /files/{groupId}/{fileName} {
    allow read: if resource.metadata.owner == request.auth.token.groupId;
    allow write: if request.auth.token.groupId == groupId;
  }
}

תכונות שכירות

כדי ליישם כללים אלה, הגדר ריבוי דירות ב-Google Cloud Identity Platform (GCIP) ולאחר מכן נצל את הדייר בכללים שלך. הדוגמאות הבאות מאפשרות כתיבה ממשתמש בדייר ספציפי, למשל tenant2-m6tyz

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // For tenant-based access control, check for a tenantID
    allow write: if request.auth.token.firebase.tenant == 'tenant2-m6tyz';
    allow read: true;
  }
}

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

{
  "rules": {
    "some_path": {
      "$uid": {
        // Only allow reads and writes if user belongs to a specific tenant
        ".write": "auth.uid !== null && auth.token.firebase.tenant === 'tenant2-m6tyz'",
        ".read": "auth.uid !== null
      }
    }
  }
}

אחסון בענן

service firebase.storage {
  // Only allow reads and writes if user belongs to a specific tenant
  match /files/{tenantId}/{fileName} {
    allow read: if request.auth != null;
    allow write: if request.auth.token.firebase.tenant == tenantId;
  }
}