ساختار قوانین امنیتی Cloud Firestore

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

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

اعلامیه سرویس و پایگاه داده

Cloud Firestore Security Rules همیشه با اعلان زیر شروع می شود:

service cloud.firestore {
  match /databases/{database}/documents {
    // ...
  }
}

اعلان service cloud.firestore قوانین را در Cloud Firestore قرار می دهد و از تداخل بین Cloud Firestore Security Rules و قوانین سایر محصولات مانند Cloud Storage جلوگیری می کند.

اعلامیه match /databases/{database}/documents مشخص می کند که قوانین باید با هر پایگاه داده Cloud Firestore در پروژه مطابقت داشته باشند. در حال حاضر هر پروژه تنها دارای یک پایگاه داده به نام (default) است.

قوانین اولیه خواندن/نوشتن

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

service cloud.firestore {
  match /databases/{database}/documents {

    // Match any document in the 'cities' collection
    match /cities/{city} {
      allow read: if <condition>;
      allow write: if <condition>;
    }
  }
}

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

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

عملیات دانه بندی

در برخی مواقع، تقسیم read و write به عملیات ریزتر مفید است. برای مثال، ممکن است برنامه شما بخواهد شرایط متفاوتی را در ایجاد سند نسبت به حذف سند اعمال کند. یا ممکن است بخواهید اجازه خواندن یک سند را بدهید اما درخواست های بزرگ را رد کنید.

یک قانون read را می توان به get و list تقسیم کرد، در حالی که یک قانون write را می توان به create ، update و delete تقسیم کرد:

service cloud.firestore {
  match /databases/{database}/documents {
    // A read rule can be divided into get and list rules
    match /cities/{city} {
      // Applies to single document read requests
      allow get: if <condition>;

      // Applies to queries and collection read requests
      allow list: if <condition>;
    }

    // A write rule can be divided into create, update, and delete rules
    match /cities/{city} {
      // Applies to writes to nonexistent documents
      allow create: if <condition>;

      // Applies to writes to existing documents
      allow update: if <condition>;

      // Applies to delete operations
      allow delete: if <condition>;
    }
  }
}

داده های سلسله مراتبی

داده ها در 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>;
    }
  }
}

حروف عام بازگشتی

اگر می خواهید قوانینی برای یک سلسله مراتب عمیق دلخواه اعمال شوند، از دستور عام بازگشتی، {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 شامل کل بخش مسیر منطبق خواهد بود، حتی اگر سند در یک زیر مجموعه عمیق تو در تو قرار داشته باشد. برای مثال، قوانین فهرست شده در بالا با سندی مطابقت دارد که در /cities/SF/landmarks/coit_tower قرار دارد و مقدار متغیر document SF/landmarks/coit_tower خواهد بود.

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

نسخه 1

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

نویسه‌های عام بازگشتی باید در انتهای یک بیانیه مسابقه بیایند.

نسخه 2

در نسخه 2 قوانین امنیتی، حروف عام بازگشتی با صفر یا چند آیتم مسیر مطابقت دارند. 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>;
    }
  }
}

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

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

اگر از جستارهای گروه مجموعه استفاده می کنید، باید از نسخه 2 استفاده کنید، به ایمن سازی پرس و جوهای گروه مجموعه مراجعه کنید.

همپوشانی بیانیه های مسابقه

ممکن است یک سند با بیش از یک 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 or subcollections.
    match /cities/{document=**} {
      allow read, write: if true;
    }
  }
}

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

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

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

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

    برای مثال، تصور کنید یک درخواست نوشتن دسته‌ای با 3 عملیات نوشتن ایجاد می‌کنید و قوانین امنیتی شما از 2 تماس دسترسی به سند برای تأیید اعتبار هر نوشتن استفاده می‌کنند. در این حالت، هر نوشتن از 2 تماس از 10 تماس دسترسی خود استفاده می کند و درخواست نوشتن دسته ای از 6 تماس از 20 تماس دسترسی خود استفاده می کند.

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

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

حداکثر عمق بیانیه match تو در تو 10
حداکثر طول مسیر، در بخش‌های مسیر، در مجموعه‌ای از عبارات match تودرتو مجاز است 100
حداکثر تعداد متغیرهای ثبت مسیر در مجموعه ای از عبارات match تودرتو مجاز است 20
حداکثر عمق فراخوانی تابع 20
حداکثر تعداد آرگومان های تابع 7
حداکثر تعداد اتصالات متغیر let در هر تابع 10
حداکثر تعداد فراخوانی های تابع بازگشتی یا چرخه ای 0 (مجاز نیست)
حداکثر تعداد عبارات ارزیابی شده در هر درخواست 1000
حداکثر اندازه یک مجموعه قوانین مجموعه قوانین باید از دو محدودیت اندازه تبعیت کند:
  • محدودیت 256 کیلوبایتی در اندازه منبع متن قوانین که از کنسول Firebase یا از CLI با استفاده از firebase deploy منتشر شده است.
  • یک محدودیت 250 کیلوبایتی در اندازه مجموعه قوانین کامپایل شده که زمانی حاصل می شود که Firebase منبع را پردازش کرده و آن را در back-end فعال می کند.

مراحل بعدی