قوانین اساسی امنیت

Firebase Security Rules به شما امکان می دهد دسترسی به داده های ذخیره شده خود را کنترل کنید. سینتکس قوانین انعطاف پذیر به این معنی است که می توانید قوانینی را ایجاد کنید که با هر چیزی مطابقت داشته باشد، از همه نوشته ها گرفته تا کل پایگاه داده تا عملیات روی یک سند خاص.

این راهنما برخی از موارد استفاده اساسی‌تری را که ممکن است بخواهید هنگام راه‌اندازی برنامه و محافظت از داده‌های خود پیاده‌سازی کنید، توضیح می‌دهد. با این حال، قبل از شروع نوشتن قوانین، ممکن است بخواهید درباره زبانی که به آن نوشته شده و رفتار آنها بیشتر بدانید.

برای دسترسی و به‌روزرسانی قوانین خود، مراحل ذکر شده در مدیریت و استقرار Firebase Security Rules دنبال کنید.

قوانین پیش فرض: حالت قفل شده

وقتی یک پایگاه داده یا نمونه ذخیره‌سازی در کنسول 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 request.auth != null;
    }
  }
}

قوانین توسعه – محیط زیست

در حالی که روی برنامه خود کار می کنید، ممکن است بخواهید دسترسی نسبتاً باز یا بدون محدودیت به داده های خود داشته باشید. فقط مطمئن شوید که Rules خود را قبل از استقرار برنامه خود در تولید به روز کنید. همچنین به یاد داشته باشید که اگر برنامه خود را اجرا کنید، برای عموم قابل دسترسی است - حتی اگر آن را راه‌اندازی نکرده باشید.

به یاد داشته باشید که Firebase به مشتریان اجازه دسترسی مستقیم به داده‌های شما را می‌دهد و Firebase Security Rules تنها محافظی است که دسترسی کاربران مخرب را مسدود می‌کند. تعریف قوانین جدا از منطق محصول چندین مزیت دارد: کلاینت ها مسئول اجرای امنیت نیستند، پیاده سازی های باگ داده های شما را به خطر نمی اندازند، و مهمتر از همه، شما برای محافظت از داده ها در برابر جهان به یک سرور واسطه متکی نیستید.

همه کاربران تایید شده

اگرچه توصیه نمی‌کنیم که داده‌های خود را برای هر کاربری که به سیستم وارد شده است در دسترس قرار دهید، ممکن است هنگام توسعه برنامه خود تنظیم دسترسی برای هر کاربر تأیید شده مفید باشد.

Cloud Firestore

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

Realtime Database

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

Cloud Storage

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      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}/{documents=**} {
      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>/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 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>/path/to/file.txt"
    match /user/{userId}/{allPaths=**} {
      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 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";
   }
  }
}

Realtime Database

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

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