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

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

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

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

כדי לקבל עזרה מ-AI, מעתיקים את ההנחיה שלמטה לסוכן תכנות מבוסס-AI (כמו Gemini ב-Android Studio,‏ Antigravity,‏ Claude Code,‏ Codex ו-Cursor). אתם יכולים להתאים אישית את ההנחיה ולשפר אותה בעזרת הסוכן. מידע מפורט על ההתקנה זמין במאמר בנושא סקילים של נציגים ב-Firebase.

Help me use Firebase in my app.
1. Make sure that **Firebase agent skills** are installed and updated. For Claude Code, Codex, or Cursor agents, help me install the Firebase plugin. For other agents, run `npx skills add firebase/agent-skills`. Always try to use **Firebase agent skills** for Firebase-related tasks.
2. Help me write, validate, and deploy Firebase Security Rules to protect my app's data.

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

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

Cloud Firestore

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

Realtime Database

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

Cloud Storage

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

כללים של סביבת פיתוח

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

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

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

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

Cloud Firestore

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

Realtime Database

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

Cloud Storage

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

כללים שמוכנים לייצור

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

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

גישה רק לבעלי התוכן

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

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

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

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

Cloud Firestore

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

Realtime Database

{
  "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"
      }
    }
  }
}

Cloud Storage

// Grants a user access to a node matching their user ID
service firebase.storage {
  match /b/{bucket}/o {
    // Files look like: "user/<UID>/file.txt"
    match /user/{userId}/{fileName} {
      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 public reads
      allow read: if true
      // Allow creation if the current user owns the new document
      allow create: if request.auth.uid == request.resource.data.author_uid;
      // Allow updates by the owner, and prevent change of ownership
      allow update: if request.auth.uid == request.resource.data.author_uid
                    && request.auth.uid == resource.data.author_uid;
      // Allow deletion if the current user owns the existing document
      allow delete: if request.auth.uid == resource.data.author_uid;
    }
  }
}

Realtime Database

{
// 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"
      }
    }
  }
}

Cloud Storage

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

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

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

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

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

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

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

מאפיינים ותפקידים שמוגדרים על ידי נתונים

הכללים האלה פועלים רק ב-Cloud Firestore וב-Realtime Database.

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"
   }
  }
}

Realtime Database

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

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

כדי להטמיע את הכללים האלה, צריך להגדיר טענות מותאמות אישית ב-Firebase Authentication ואז להשתמש בטענות בכללים.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // For attribute-based access control, check for an administrator 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";
   }
  }
}

Realtime Database

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

Cloud Storage

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;
  }
}

Realtime Database

{
  "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
      }
    }
  }
}

Cloud Storage

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;
  }
}