قوانین امنیتی چگونه کار می کند

امنیت می‌تواند یکی از پیچیده‌ترین قطعات پازل توسعه برنامه باشد. در اکثر برنامه‌ها، توسعه‌دهندگان باید سروری را بسازند و اجرا کنند که احراز هویت (اینکه کاربر کیست) و مجوزدهی (آنچه کاربر می‌تواند انجام دهد) را مدیریت کند.

Firebase Security Rules لایه میانی (سرور) را حذف می‌کنند و به شما امکان می‌دهند مجوزهای مبتنی بر مسیر را برای کلاینت‌هایی که مستقیماً به داده‌های شما متصل می‌شوند، مشخص کنید. برای کسب اطلاعات بیشتر در مورد نحوه اعمال قوانین بر درخواست‌های ورودی، از این راهنما استفاده کنید.

برای کسب اطلاعات بیشتر در مورد قوانین یک محصول، آن را انتخاب کنید.

Cloud Firestore

ساختار پایه

Firebase Security Rules در Cloud Firestore و Cloud Storage از ساختار و سینتکس زیر استفاده می‌کنند:

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

مفاهیم کلیدی زیر برای درک هنگام تدوین قوانین مهم هستند:

  • درخواست (Request): متد یا متدهایی که در دستور allow فراخوانی می‌شوند. این‌ها متدهایی هستند که شما اجازه اجرا شدن آن‌ها را می‌دهید. متدهای استاندارد عبارتند از: get ، list ، create ، update و delete . متدهای مربوط به read و write ، دسترسی گسترده به خواندن و نوشتن را در پایگاه داده یا مسیر ذخیره‌سازی مشخص شده فراهم می‌کنند.
  • مسیر: پایگاه داده یا محل ذخیره‌سازی، که به صورت یک مسیر URI نمایش داده می‌شود.
  • قانون: دستور allow که شامل شرطی است که در صورت درست بودن ارزیابی درخواست، آن را مجاز می‌کند.

قوانین امنیتی نسخه ۲

از ماه مه ۲۰۱۹، نسخه ۲ قوانین امنیتی Firebase اکنون در دسترس است. نسخه ۲ این قوانین، رفتار کاراکترهای بازگشتی {name=**} را تغییر می‌دهد. اگر قصد استفاده از پرس‌وجوهای گروهی مجموعه را دارید، باید از نسخه ۲ استفاده کنید. باید با قرار دادن rules_version = '2'; در خط اول قوانین امنیتی خود، نسخه ۲ را انتخاب کنید:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

مسیرهای منطبق

همه دستورات match باید به اسناد اشاره کنند، نه مجموعه‌ها. یک دستور match می‌تواند به یک سند خاص اشاره کند، مانند match /cities/SF یا از کاراکترهای wildcard برای اشاره به هر سندی در مسیر مشخص شده استفاده کند، مانند match /cities/{city} .

در این مثال، دستور match از سینتکس wildcard {city} استفاده می‌کند. این بدان معناست که این قانون برای هر سندی در مجموعه cities ، مانند /cities/SF یا /cities/NYC ، اعمال می‌شود. هنگامی که عبارات allow در دستور match ارزیابی می‌شوند، متغیر city به نام سند city، مانند SF یا NYC ، تبدیل می‌شود.

تطبیق زیرمجموعه‌ها

داده‌ها در Cloud Firestore در مجموعه‌ای از اسناد سازماندهی شده‌اند و هر سند می‌تواند سلسله مراتب را از طریق زیرمجموعه‌ها گسترش دهد. درک چگونگی تعامل قوانین امنیتی با داده‌های سلسله مراتبی مهم است.

وضعیتی را در نظر بگیرید که هر سند در مجموعه cities شامل یک زیرمجموعه landmarks باشد. قوانین امنیتی فقط در مسیر منطبق اعمال می‌شوند، بنابراین کنترل‌های دسترسی تعریف شده در مجموعه cities به زیرمجموعه landmarks اعمال نمی‌شوند. در عوض، قوانین صریحی برای کنترل دسترسی به زیرمجموعه‌ها بنویسید:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      allow read, write: if <condition>;

      // Explicitly define rules for the 'landmarks' subcollection
      match /landmarks/{landmark} {
        allow read, write: if <condition>;
      }
    }
  }
}

هنگام تودرتو کردن دستورات match ، مسیر دستور match داخلی همیشه نسبت به مسیر دستور match خارجی است. بنابراین، مجموعه قوانین زیر معادل هستند:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      match /landmarks/{landmark} {
        allow read, write: if <condition>;
      }
    }
  }
}
service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city}/landmarks/{landmark} {
      allow read, write: if <condition>;
    }
  }
}

همپوشانی دستورات تطابق

ممکن است یک سند با بیش از یک عبارت match مطابقت داشته باشد. در صورتی که چندین عبارت allow با یک درخواست مطابقت داشته باشند، در صورت true بودن هر یک از شرایط زیر، دسترسی مجاز است:

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the 'cities' collection.
    match /cities/{city} {
      allow read, write: if false;
    }

    // Matches any document in the 'cities' collection.
    match /cities/{document} {
      allow read, write: if true;
    }
  }
}

در این مثال، تمام خواندن‌ها و نوشتن‌ها در مجموعه cities مجاز خواهد بود زیرا قانون دوم همیشه true است، حتی اگر قانون اول همیشه false باشد.

نویسه‌های عام بازگشتی

اگر می‌خواهید قوانین بر روی یک سلسله مراتب دلخواه اعمال شوند، از سینتکس بازگشتی wildcard، {name=**} استفاده کنید:

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

هنگام استفاده از سینتکس بازگشتی wildcard، متغیر wildcard شامل کل بخش مسیر منطبق خواهد بود، حتی اگر سند در یک زیرمجموعه تو در تو قرار داشته باشد. برای مثال، قوانین ذکر شده با سندی که در /cities/SF/landmarks/coit_tower قرار دارد، مطابقت دارند و مقدار متغیر document SF/landmarks/coit_tower خواهد بود.

با این حال، توجه داشته باشید که رفتار کاراکترهای جایگزین بازگشتی به نسخه قوانین بستگی دارد.

نسخه ۱

قوانین امنیتی به طور پیش‌فرض از نسخه ۱ استفاده می‌کنند. در نسخه ۱، کاراکترهای جایگزین بازگشتی با یک یا چند مورد مسیر مطابقت دارند. آن‌ها با یک مسیر خالی مطابقت ندارند، بنابراین match /cities/{city}/{document=**} با اسناد موجود در زیرمجموعه‌ها مطابقت دارد اما با اسناد موجود در مجموعه cities مطابقت ندارد، در حالی که match /cities/{document=**} با هر دو سند موجود در مجموعه cities و زیرمجموعه‌ها مطابقت دارد.

کاراکترهای جایگزین بازگشتی باید در انتهای یک دستور match قرار گیرند.

نسخه ۲

در نسخه ۲ قوانین امنیتی، کاراکترهای جایگزین بازگشتی با صفر یا چند مورد مسیر مطابقت دارند. match/cities/{city}/{document=**} اسناد را در هر زیرمجموعه و همچنین اسناد موجود در مجموعه cities مطابقت می‌دهد.

شما باید با اضافه کردن rules_version = '2'; در بالای قوانین امنیتی خود، نسخه ۲ را فعال کنید:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{city}/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

شما می‌توانید حداکثر یک کاراکتر جایگزین بازگشتی برای هر دستور match داشته باشید، اما در نسخه ۲، می‌توانید این کاراکتر جایگزین را در هر جایی از دستور match قرار دهید. برای مثال:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the songs collection group
    match /{path=**}/songs/{song} {
      allow read, write: if <condition>;
    }
  }
}

اگر از کوئری‌های گروه‌های مجموعه استفاده می‌کنید، باید از نسخه ۲ آن استفاده کنید، به بخش ایمن‌سازی کوئری‌های گروه‌های مجموعه مراجعه کنید.

محدودیت‌های قانون امنیتی

هنگام کار با قوانین امنیتی، به محدودیت‌های زیر توجه کنید:

حد جزئیات
حداکثر تعداد فراخوانی‌های exists() ، get() و getAfter() به ازای هر درخواست
  • ۱۰ برای درخواست‌های تک سندی و درخواست‌های استعلام.
  • ۲۰ برای خواندن‌های چند سندی، تراکنش‌ها و نوشتن‌های دسته‌ای. محدودیت قبلی ۱۰ برای هر عملیات نیز اعمال می‌شود.

    برای مثال، تصور کنید که یک درخواست نوشتن دسته‌ای با ۳ عملیات نوشتن ایجاد می‌کنید و قوانین امنیتی شما از ۲ فراخوانی دسترسی به سند برای اعتبارسنجی هر نوشتن استفاده می‌کنند. در این حالت، هر نوشتن از ۲ فراخوانی از ۱۰ فراخوانی دسترسی خود استفاده می‌کند و درخواست نوشتن دسته‌ای از ۶ فراخوانی از ۲۰ فراخوانی دسترسی خود استفاده می‌کند.

تجاوز از هر یک از این محدودیت‌ها منجر به خطای عدم اجازه دسترسی می‌شود.

برخی از فراخوانی‌های دسترسی به سند ممکن است در حافظه پنهان ذخیره شوند و فراخوانی‌های ذخیره شده در حافظه پنهان جزو محدودیت‌ها محسوب نمی‌شوند.

حداکثر عمق عبارت match تو در تو ۱۰
حداکثر طول مسیر، در بخش‌های مسیر، مجاز در مجموعه‌ای از دستورات match تو در تو ۱۰۰
حداکثر تعداد متغیرهای ثبت مسیر مجاز در مجموعه‌ای از دستورات match تو در تو ۲۰
حداکثر عمق فراخوانی تابع ۲۰
حداکثر تعداد آرگومان‌های تابع ۷
حداکثر تعداد متغیرهای let برای هر تابع ۱۰
حداکثر تعداد فراخوانی‌های تابع بازگشتی یا چرخه‌ای ۰ (مجاز نیست)
حداکثر تعداد عبارات ارزیابی شده در هر درخواست ۱۰۰۰
حداکثر اندازه یک مجموعه قوانین مجموعه قوانین باید از دو محدودیت اندازه پیروی کنند:
  • محدودیت ۲۵۶ کیلوبایتی برای اندازه منبع متن مجموعه قوانین منتشر شده از کنسول Firebase یا از رابط خط فرمان (CLI) با استفاده از firebase deploy .
  • محدودیت ۲۵۰ کیلوبایتی برای اندازه مجموعه قوانین کامپایل‌شده که هنگام پردازش منبع توسط فایربیس و فعال کردن آن در بک‌اند ایجاد می‌شود.

Cloud Storage

ساختار پایه

Firebase Security Rules در Cloud Firestore و Cloud Storage از ساختار و سینتکس زیر استفاده می‌کنند:

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

مفاهیم کلیدی زیر برای درک هنگام تدوین قوانین مهم هستند:

  • درخواست (Request): متد یا متدهایی که در دستور allow فراخوانی می‌شوند. این‌ها متدهایی هستند که شما اجازه اجرا شدن آن‌ها را می‌دهید. متدهای استاندارد عبارتند از: get ، list ، create ، update و delete . متدهای مربوط به read و write ، دسترسی گسترده به خواندن و نوشتن را در پایگاه داده یا مسیر ذخیره‌سازی مشخص شده فراهم می‌کنند.
  • مسیر: پایگاه داده یا محل ذخیره‌سازی، که به صورت یک مسیر URI نمایش داده می‌شود.
  • قانون: دستور allow که شامل شرطی است که در صورت درست بودن ارزیابی درخواست، آن را مجاز می‌کند.

مسیرهای منطبق

Cloud Storage Security Rules مسیرهای فایل مورد استفاده برای دسترسی به فایل‌ها در Cloud Storage match . قوانین می‌توانند با مسیرهای دقیق یا مسیرهای wildcard 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 یک الگو با استفاده از wildcards استفاده کرد. wildcard یک متغیر نامگذاری شده است که یا یک رشته واحد مانند profilePhoto.png یا چندین بخش مسیر مانند images/profilePhoto.png را نشان می‌دهد.

یک wildcard با اضافه کردن آکولاد در اطراف نام wildcard، مانند {string} ایجاد می‌شود. یک wildcard چند بخشی را می‌توان با اضافه کردن =** به نام wildcard، مانند {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 است.

یک متغیر wildcard می‌تواند از درون match نام فایل یا مسیر مجوز، ارجاع داده شود:

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

Cloud Storage Security Rules (cascade) اجرا نمی‌شوند و قوانین فقط زمانی ارزیابی می‌شوند که مسیر درخواست با مسیری که قوانین مشخص شده است، مطابقت داشته باشد.

درخواست ارزیابی

آپلودها، دانلودها، تغییرات متادیتا و حذف‌ها با استفاده از request ارسال شده به Cloud Storage ارزیابی می‌شوند. متغیر request شامل مسیری است که درخواست در آن انجام می‌شود، زمانی که درخواست دریافت شده است و اگر درخواست از نوع نوشتن باشد، مقدار resource جدید را شامل می‌شود. هدرهای HTTP و وضعیت احراز هویت نیز گنجانده شده‌اند.

شیء request همچنین شامل شناسه منحصر به فرد کاربر و بار داده Firebase Authentication در شیء request.auth است که در بخش احراز هویت مستندات بیشتر توضیح داده خواهد شد.

لیست کاملی از ویژگی‌های موجود در شیء request در زیر موجود است:

ملک نوع توضیحات
auth نقشه<رشته، رشته> وقتی کاربری وارد سیستم می‌شود، uid ، شناسه منحصر به فرد کاربر، و token ، نقشه‌ای از ادعاهای Firebase Authentication JWT، را ارائه می‌دهد. در غیر این صورت، null خواهد بود.
params نقشه<رشته، رشته> نقشه‌ای که شامل پارامترهای پرس‌وجوی درخواست است.
path مسیر path نشان دهنده مسیری است که درخواست در آن انجام می‌شود.
resource نقشه<رشته، رشته> مقدار منبع جدید، فقط در درخواست‌های write نمایش داده می‌شود.
time مهر زمانی یک مهر زمانی که نشان دهنده زمان سرور برای ارزیابی درخواست است.

ارزیابی منابع

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

Firebase Security Rules برای Cloud Storage فراداده‌های فایل را در شیء resource ارائه می‌دهد که شامل جفت‌های کلید/مقدار فراداده‌های نمایش داده شده در یک شیء Cloud Storage است. این ویژگی‌ها را می‌توان در درخواست‌های read یا write بررسی کرد تا از صحت داده‌ها اطمینان حاصل شود.

در درخواست‌های write (مانند آپلود، به‌روزرسانی فراداده و حذف)، علاوه بر شیء resource ، که شامل فراداده‌های فایل برای فایلی است که در مسیر درخواست وجود دارد، شما همچنین می‌توانید از شیء request.resource استفاده کنید که شامل زیرمجموعه‌ای از فراداده‌های فایل است که در صورت مجاز بودن نوشتن، باید نوشته شوند. می‌توانید از این دو مقدار برای اطمینان از یکپارچگی داده‌ها یا اعمال محدودیت‌های برنامه مانند نوع یا اندازه فایل استفاده کنید.

لیست کاملی از ویژگی‌های موجود در شیء resource در دسترس است:

ملک نوع توضیحات
name رشته نام کامل شیء
bucket رشته نام سطلی که این شیء در آن قرار دارد.
generation عدد صحیح نسل شیء Google Cloud Storage از این شیء.
metageneration عدد صحیح متا تولید شیء Google Cloud Storage از این شیء.
size عدد صحیح اندازه شیء بر حسب بایت.
timeCreated مهر زمانی یک مهر زمانی که نشان دهنده زمان ایجاد یک شیء است.
updated مهر زمانی یک مهر زمانی که نشان دهنده آخرین زمان به‌روزرسانی یک شیء است.
md5Hash رشته یک هش MD5 از شیء.
crc32c رشته یک هش crc32c از شیء.
etag رشته برچسب الکترونیکی (etag) مرتبط با این شیء.
contentDisposition رشته وضعیت محتوایی مرتبط با این شیء.
contentEncoding رشته کدگذاری محتوای مرتبط با این شیء.
contentLanguage رشته زبان محتوای مرتبط با این شیء.
contentType رشته نوع محتوای مرتبط با این شیء.
metadata نقشه<رشته، رشته> جفت‌های کلید/مقدار از فراداده‌های سفارشی اضافی و مشخص‌شده توسط توسعه‌دهنده.

request.resource شامل همه این موارد به استثنای generation ، metageneration ، etag ، timeCreated و updated .

محدودیت‌های قوانین امنیتی

هنگام کار با قوانین امنیتی، به محدودیت‌های زیر توجه کنید:

حد جزئیات
حداکثر تعداد فراخوانی‌های firestore.exists() و firestore.get() به ازای هر درخواست

۲ برای درخواست‌های تک سندی و درخواست‌های استعلام.

تجاوز از این حد منجر به خطای عدم اجازه دسترسی می‌شود.

تماس‌های دسترسی به اسناد مشابه ممکن است در حافظه پنهان ذخیره شوند و تماس‌های ذخیره شده در حافظه پنهان جزو محدودیت‌ها محسوب نمی‌شوند.

مثال کامل

با کنار هم قرار دادن همه این موارد، می‌توانید یک مثال کامل از قوانین برای یک راهکار ذخیره‌سازی تصویر ایجاد کنید:

service firebase.storage {
 match /b/{bucket}/o {
   match /images {
     // 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
     // 4) Filename (stored in imageId wildcard variable) is less than 32 characters
     match /{imageId} {
       allow read;
       allow write: if request.resource.size < 5 * 1024 * 1024
                    && request.resource.contentType.matches('image/.*')
                    && request.resource.contentType == resource.contentType
                    && imageId.size() < 32
     }
   }
 }
}

Realtime Database

ساختار پایه

در Realtime Database ، Firebase Security Rules شامل عباراتی شبیه به جاوا اسکریپت هستند که در یک سند JSON قرار دارند.

آنها از سینتکس زیر استفاده می‌کنند:

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

سه عنصر اساسی در این قاعده وجود دارد:

  • مسیر: مکان پایگاه داده. این ساختار JSON پایگاه داده شما را منعکس می‌کند.
  • درخواست: اینها روش‌هایی هستند که قانون برای اعطای دسترسی استفاده می‌کند. قوانین read و write ، دسترسی گسترده خواندن و نوشتن را اعطا می‌کنند، در حالی که قوانین validate به عنوان یک تأیید ثانویه برای اعطای دسترسی بر اساس داده‌های ورودی یا موجود عمل می‌کنند.
  • شرط: شرطی که در صورت درست بودن ارزیابی درخواست، آن را مجاز می‌کند.

نحوه اعمال قوانین بر مسیرها

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

قوانین زیر را در نظر بگیرید:

{
  "rules": {
     "foo": {
        // allows read to /foo/*
        ".read": "data.child('baz').val() === true",
        "bar": {
          // ignored, since read was allowed already
          ".read": false
        }
     }
  }
}

این ساختار امنیتی اجازه می‌دهد تا /bar/ هر زمان که /foo/ حاوی یک baz فرزند با مقدار true باشد، خوانده شود. دستور ".read": false در /foo/bar/ در اینجا هیچ تاثیری ندارد، زیرا دسترسی توسط یک مسیر فرزند قابل لغو نیست.

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

با این حال، قوانین .validate آبشاری نیستند. برای اینکه نوشتن مجاز باشد، باید تمام قوانین اعتبارسنجی در تمام سطوح سلسله مراتب رعایت شوند.

علاوه بر این، از آنجا که قوانین به مسیر والد اعمال نمی‌شوند، اگر قانونی در مکان درخواستی یا در مکان والد که دسترسی را اعطا می‌کند وجود نداشته باشد، عملیات خواندن یا نوشتن با شکست مواجه می‌شود. حتی اگر هر مسیر فرزند تحت تأثیر قابل دسترسی باشد، خواندن در مکان والد کاملاً با شکست مواجه خواهد شد. این ساختار را در نظر بگیرید:

{
  "rules": {
    "records": {
      "rec1": {
        ".read": true
      },
      "rec2": {
        ".read": false
      }
    }
  }
}

بدون درک اینکه قوانین به صورت اتمی ارزیابی می‌شوند، ممکن است به نظر برسد که واکشی مسیر /records/ rec1 برمی‌گرداند اما rec2 برنمی‌گرداند. با این حال، نتیجه واقعی یک خطا است:

جاوا اسکریپت
var db = firebase.database();
db.ref("records").once("value", function(snap) {
  // success method is not called
}, function(err) {
  // error callback triggered with PERMISSION_DENIED
});
هدف-سی
توجه: این محصول Firebase در App Clip target موجود نیست.
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
[[_ref child:@"records"] observeSingleEventOfType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) {
  // success block is not called
} withCancelBlock:^(NSError * _Nonnull error) {
  // cancel block triggered with PERMISSION_DENIED
}];
سویفت
توجه: این محصول Firebase در App Clip target در دسترس نیست.
var ref = FIRDatabase.database().reference()
ref.child("records").observeSingleEventOfType(.Value, withBlock: { snapshot in
    // success block is not called
}, withCancelBlock: { error in
    // cancel block triggered with PERMISSION_DENIED
})
جاوا
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("records");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    // success method is not called
  }

  @Override
  public void onCancelled(FirebaseError firebaseError) {
    // error callback triggered with PERMISSION_DENIED
  });
});
استراحت
curl https://docs-examples.firebaseio.com/rest/records/
# response returns a PERMISSION_DENIED error

از آنجایی که عملیات خواندن در /records/ اتمیک است و هیچ قانون خواندنی وجود ندارد که دسترسی به تمام داده‌های زیر /records/ را اعطا کند، این امر خطای PERMISSION_DENIED را ایجاد می‌کند. اگر این قانون را در شبیه‌ساز امنیتی در کنسول Firebase خود ارزیابی کنیم، می‌توانیم ببینیم که عملیات خواندن رد شده است:

Attempt to read /records with auth=Success(null)
    /
    /records

No .read rule allowed the operation.
Read was denied.

این عملیات رد شد زیرا هیچ قانون خواندنی اجازه دسترسی به مسیر /records/ را نمی‌داد، اما توجه داشته باشید که قانون مربوط به rec1 هرگز ارزیابی نشد زیرا در مسیری که ما درخواست کردیم نبود. برای دریافت rec1 ، باید مستقیماً به آن دسترسی پیدا کنیم:

جاوا اسکریپت
var db = firebase.database();
db.ref("records/rec1").once("value", function(snap) {
  // SUCCESS!
}, function(err) {
  // error callback is not called
});
هدف-سی
توجه: این محصول Firebase در App Clip target در دسترس نیست.
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
[[ref child:@"records/rec1"] observeSingleEventOfType:FEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) {
    // SUCCESS!
}];
سویفت
توجه: این محصول Firebase در App Clip target موجود نیست.
var ref = FIRDatabase.database().reference()
ref.child("records/rec1").observeSingleEventOfType(.Value, withBlock: { snapshot in
    // SUCCESS!
})
جاوا
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("records/rec1");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    // SUCCESS!
  }

  @Override
  public void onCancelled(FirebaseError firebaseError) {
    // error callback is not called
  }
});
استراحت
curl https://docs-examples.firebaseio.com/rest/records/rec1
# SUCCESS!

متغیر مکان

Rules Realtime Database از متغیر $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 }
      }
    }
  }