Google is committed to advancing racial equity for Black communities. See how.
این صفحه به‌وسیله ‏Cloud Translation API‏ ترجمه شده است.
Switch to English

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

قوانین امنیتی Firebase به زبانهای سفارشی و انعطاف پذیر ، قدرتمندی پشتیبانی می کند که طیف گسترده ای از پیچیدگی و گرانول بودن را پشتیبانی می کند. شما می توانید قوانین خود را به عنوان خاص یا به طور کلی به معنای برنامه خود حس کنید. قوانین پایگاه داده Realtime از نحوهایی استفاده می کنند که مانند ساختار JavaScript در یک ساختار JSON است. قوانین Cloud Firestore و Cloud Storage از زبانی مبتنی بر زبان عبارات مشترک (CEL) استفاده می کنند ، که بر روی CEL با match و allow بیانیه هایی را پشتیبانی کند که از دسترسی مشروط برخوردار باشند.

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

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

ساختار اساسی

Cloud Firestore

قوانین امنیتی Firebase در Cloud Firestore و Storage از ساختار و نحو زیر استفاده می کنند:

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

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

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

هر یک از این مفاهیم با جزئیات بیشتر در زیر توضیح داده شده است.

فضای ذخیره ابری

قوانین امنیتی Firebase در Cloud Firestore و Storage از ساختار و نحو زیر استفاده می کنند:

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

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

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

هر یک از این مفاهیم با جزئیات بیشتر در زیر توضیح داده شده است.

بانک اطلاعات املاک و مستغلات

در Realtime Database ، قوانین امنیتی Firebase از عبارات مشابه JavaScript موجود در یک سند JSON است.

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

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

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

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

ساختار قانون

Cloud Firestore

عناصر اصلی یک قانون در Cloud Firestore و Cloud Storage به شرح زیر است:

  • بیانیه service : محصول Firebase را که قوانینی برای آن اعمال می شود اعلام می کند.
  • بلوک match : مسیری را در بانک اطلاعاتی یا سطل ذخیره سازی که قوانینی برای آن اعمال می شود ، تعریف می کند.
  • جمله allow : شرایط برای دسترسی ، شرایط متمایز شده را فراهم می کند. روشهای پشتیبانی شده عبارتند از: get ، list ، create ، update ، delete و روشهای راحت read و write .
  • اعلامیه های function اختیاری: امکان ترکیب و بسته بندی شرایط را برای استفاده در چندین قانون فراهم می کند.

این service شامل یک یا چند بلوک match با بیانیه های allow است که شرایط دسترسی به درخواست ها را فراهم می کند. متغیرهای request و resource برای استفاده در شرایط قانون در دسترس هستند. زبان قوانین امنیت Firebase همچنین اعلامیه های function پشتیبانی می function .

نسخه نحو

جمله syntax نسخه نسخه Firebase Rules را برای نوشتن منبع استفاده می کند. آخرین نسخه زبان v2 .

 rules_version = '2';
service cloud.firestore {
...
}
 

اگر هیچ rules_version ارائه نشده باشد ، قوانین شما با استفاده از موتور v1 ارزیابی می شود.

سرویس

service تعریف بیانیه که محصول فایربیس، و یا خدمات، قوانین خود را اعمال می شود. شما فقط می توانید در هر پرونده منبع یک اظهارنامه service .

Cloud Firestore

 service cloud.firestore {
 // Your 'match' blocks with their corresponding 'allow' statements and
 // optional 'function' declarations are contained here
}
 

ذخیره سازی

 service firebase.storage {
  // Your 'match' blocks with their corresponding 'allow' statements and
  // optional 'function' declarations are contained here
}
 

اگر شما با استفاده از Firebase CLI قوانینی را برای Cloud Firestore و Storage تعریف می کنید ، باید آنها را در پرونده های جداگانه حفظ کنید.

همخوانی داشتن

match بلوک اعلام path الگوی است که در برابر مسیر برای عملیات درخواستی همسان (ورودی request.path ). بدنه match باید دارای یک یا چند بلوک match تو match تو باشد ، allow بیانیه ها یا اعلامیه های function . مسیر بلوک های match تو در تو ، نسبت به مسیر موجود در بلوک match والدین است.

الگوی path نامی مانند دایرکتوری است که ممکن است متغیرها یا کارتهای عادی باشد. الگوی path اجازه می دهد تا مسابقات یک قطعه و مسیرهای چند مسیره انجام شود. متغیرهای محدود شده در یک path در محدوده match یا هر محدوده تودرتو که در آن path اعلام شده است قابل مشاهده است

مسابقات برابر الگوی path ممکن است جزئی یا کامل باشد:

  • مسابقات جزئی: این path الگوی یک پیشوند بازی از است request.path .
  • بازی کامل: path الگوی منطبق کل request.path .

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

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

 // Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
  // Partial match.
  match /example/{singleSegment} {   // `singleSegment` == 'hello'
    allow write;                     // Write rule not evaluated.
    // Complete match.
    match /nested/path {             // `singleSegment` visible in scope.
      allow read;                    // Read rule is evaluated.
    }
  }
  // Complete match.
  match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
    allow read;                      // Read rule is evaluated.
  }
}
 

همانطور که مثال بالا نشان می دهد ، اعلامیه های path متغیرهای زیر را پشتیبانی می کند:

  • wildcard single-part: یک متغیر wildcard در یک مسیر با پیچیدن متغیر در بندهای فرفری اعلام می شود: {variable} . این متغیر در متن match به عنوان یک string قابل دسترسی است.
  • کارت ویزیت بازگشتی: علامت بازگشتی یا چند قسمتی ، wildcard با بخشهای مختلف مسیر در یا زیر یک مسیر مطابقت دارد. این کارت ویزیت با تمام مسیرهای زیر محلی که آن را تنظیم کرده اید مطابقت دارد. می توانید آن را با اضافه کردن رشته =** در انتهای متغیر بخش خود اعلام کنید: {variable=**} . این متغیر در جمله match به عنوان یک شی path قابل دسترسی است.

اجازه

بلوک match شامل یک یا چند بیانیه allow است. این قوانین واقعی شما هستند. شما می توانید درخواست allow به یک یا چند روش قوانین. شرایط موجود در بیانیه allow باید برای Cloud Firestore یا Storage برای تأیید هرگونه درخواست ورودی صحیح ارزیابی شود. شما همچنین می توانید بیانیه های allow را بدون شرایط بنویسید ، به عنوان مثال ، allow read . اگر بیانیه allow یک شرط را شامل نشود ، همیشه درخواست آن روش را مجاز می سازد.

در صورت رضایت هر یک از قوانین allow برای این روش ، درخواست مجاز است. علاوه بر این ، اگر یک قانون گسترده تر به شما دسترسی می دهد ، قوانین دسترسی را اجازه می دهند و هرگونه قوانین گرانوله تر که ممکن است دسترسی را محدود کند ، چشم پوشی می کنند.

مثال زیر را در نظر بگیرید ، جایی که هر کاربر می تواند هر یک از پرونده های خود را بخواند یا حذف کند. یک قانون گرانوله تر فقط اجازه می دهد تا کاربر درخواست کننده نوشتن پرونده را داشته باشد و پرونده آن PNG است. یک کاربر می تواند هر پرونده را در زیرگذر - حتی اگر آنها PNG نباشند - حذف کند زیرا قانون قبلی این اجازه را می دهد.

 service firebase.storage {
  // Allow the requestor to read or delete any resource on a path under the
  // user directory.
  match /users/{userId}/{anyUserFile=**} {
    allow read, delete: if request.auth != null && request.auth.uid == userId;
  }

  // Allow the requestor to create or update their own images.
  // When 'request.method' == 'delete' this rule and the one matching
  // any path under the user directory would both match and the `delete`
  // would be permitted.

  match /users/{userId}/images/{imageId} {
    // Whether to permit the request depends on the logical OR of all
    // matched rules. This means that even if this rule did not explicitly
    // allow the 'delete' the earlier rule would have.
    allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
  }
}
 

روش

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

روش نوع درخواست
روشهای راحتی
read هر نوع درخواست خوانده شده
write هر نوع درخواست نوشتن
روشهای استاندارد
get درخواست های مربوط به اسناد یا پرونده های مجزا را بخوانید
list درخواست های نمایش داده شد و مجموعه ها را بخوانید
create اسناد یا پرونده های جدید بنویسید
update برای اسناد یا پرونده های موجود بنویسید
delete حذف داده ها

شما نمی توانید روشهای خواندن را در همان بلوک match یا روشهای نوشتن متناقض در بیانیه همان path همپوشانی کنید.

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

 service bad.example {
  match /rules/with/overlapping/methods {
    // This rule allows reads to all unauthenticated users
    allow read: if request.auth != null;

    match another/subpath {
      // This secondary, more specific read rule causes an error
      allow get: if request.auth != null && request.auth.uid == "me";
      // Overlapping write methods in the same path cause an error as well
      allow write: if request.auth != null;
      allow create: if request.auth != null && request.auth.uid == "me";
    }
  }
}
 

تابع

با پیچیده تر شدن قوانین امنیتی ، ممکن است بخواهید مجموعه ای از شرایط را در کارکردهایی بپیچید که می توانید از مجدداً استفاده کنید. قوانین امنیتی از توابع سفارشی پشتیبانی می کنند. نحو عملکردهای سفارشی کمی شبیه JavaScript است ، اما توابع قوانین امنیتی به زبانی خاص دامنه نوشته شده است که دارای برخی محدودیت های مهم است:

  • توابع فقط می توانند یک جمله return . آنها نمی توانند منطق دیگری داشته باشند. به عنوان مثال ، آنها نمی توانند حلقه ها را اجرا کنند یا با خدمات خارجی تماس بگیرند.
  • توابع می توانند به طور خودکار به توابع و متغیرهایی از محدوده ای که در آن تعریف شده است دسترسی پیدا کنند. به عنوان مثال ، تابعی که در محدوده service cloud.firestore تعریف شده باشد ، به متغیر resource و توابع داخلی مانند get() و exists() .
  • توابع ممکن است توابع دیگری را فراخوانی کنند ، اما ممکن است دوباره بازیابی نشوند. عمق تماس پشته فراخوان به 20 محدود است.
  • در قوانین نسخه v2 ، توابع می توانند متغیرها را با استفاده از کلید واژه let تعریف کنند. توابع می توانند حداکثر 10 اجازه اتصال داشته باشند ، اما باید با بیانیه بازگشت پایان یابد.

یک تابع با کلمه کلیدی function تعریف می شود و آرگومان های صفر یا بیشتر طول می کشد. به عنوان مثال ، ممکن است بخواهید دو نوع شرط استفاده شده در مثالهای فوق را با یک عملکرد واحد ترکیب کنید:

 service cloud.firestore {
  match /databases/{database}/documents {
    // True if the user is signed in or the requested data is 'public'
    function signedInOrPublic() {
      return request.auth.uid != null || resource.data.visibility == 'public';
    }

    match /cities/{city} {
      allow read, write: if signedInOrPublic();
    }

    match /users/{user} {
      allow read, write: if signedInOrPublic();
    }
  }
}
 

در اینجا مثالی وجود دارد که آرگومانهای عملکرد را نشان می دهد و به تکالیف اجازه می دهد. بگذارید بیانیه های واگذاری باید با نیم ستون ها جدا شوند.

 function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
  return isAuthor || isAdmin;
}

 

توجه داشته باشید که چگونه تکلیف isAdmin جستجوی مجموعه سرپرستها را افزایش می دهد. برای ارزیابی تنبلی و بدون نیاز به جستجوی غیر ضروری ، از ماهیت اتصال کوتاه && (AND) و || (یا) مقایسه برای تماس با یک تابع دوم فقط در صورتی که isAuthor نشان داده شود درست است (برای && مقایسه) یا نادرست (برای || مقایسه).

 function isAdmin(userId) {
  return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  // `||` is short-circuiting; isAdmin called only if isAuthor == false.
  return isAuthor || isAdmin(userId);
}
 

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

فضای ذخیره ابری

عناصر اصلی یک قانون در Cloud Firestore و Cloud Storage به شرح زیر است:

  • بیانیه service : محصول Firebase را که قوانینی برای آن اعمال می شود اعلام می کند.
  • بلوک match : مسیری را در بانک اطلاعاتی یا سطل ذخیره سازی که قوانینی برای آن اعمال می شود ، تعریف می کند.
  • جمله allow : شرایط برای دسترسی ، شرایط متمایز شده را فراهم می کند. روشهای پشتیبانی شده عبارتند از: get ، list ، create ، update ، delete و روشهای راحت read و write .
  • اعلامیه های function اختیاری: امکان ترکیب و بسته بندی شرایط را برای استفاده در چندین قانون فراهم می کند.

این service شامل یک یا چند بلوک match با بیانیه های allow است که شرایط دسترسی به درخواست ها را فراهم می کند. متغیرهای request و resource برای استفاده در شرایط قانون در دسترس هستند. زبان قوانین امنیت Firebase همچنین اعلامیه های function پشتیبانی می function .

نسخه نحو

جمله syntax نسخه نسخه Firebase Rules را برای نوشتن منبع استفاده می کند. آخرین نسخه زبان v2 .

 rules_version = '2';
service cloud.firestore {
...
}
 

اگر هیچ rules_version ارائه نشده باشد ، قوانین شما با استفاده از موتور v1 ارزیابی می شود.

سرویس

service تعریف بیانیه که محصول فایربیس، و یا خدمات، قوانین خود را اعمال می شود. شما فقط می توانید در هر پرونده منبع یک اظهارنامه service .

Cloud Firestore

 service cloud.firestore {
 // Your 'match' blocks with their corresponding 'allow' statements and
 // optional 'function' declarations are contained here
}
 

ذخیره سازی

 service firebase.storage {
  // Your 'match' blocks with their corresponding 'allow' statements and
  // optional 'function' declarations are contained here
}
 

اگر شما با استفاده از Firebase CLI قوانینی را برای Cloud Firestore و Storage تعریف می کنید ، باید آنها را در پرونده های جداگانه حفظ کنید.

همخوانی داشتن

match بلوک اعلام path الگوی است که در برابر مسیر برای عملیات درخواستی همسان (ورودی request.path ). بدنه match باید دارای یک یا چند بلوک match تو match تو باشد ، allow بیانیه ها یا اعلامیه های function . مسیر بلوک های match تو در تو ، نسبت به مسیر موجود در بلوک match والدین است.

الگوی path نامی مانند دایرکتوری است که ممکن است متغیرها یا کارتهای عادی باشد. الگوی path اجازه می دهد تا مسابقات یک قطعه و مسیرهای چند مسیره انجام شود. متغیرهای محدود شده در یک path در محدوده match یا هر محدوده تودرتو که در آن path اعلام شده است قابل مشاهده است.

مسابقات برابر الگوی path ممکن است جزئی یا کامل باشد:

  • مسابقات جزئی: این path الگوی یک پیشوند بازی از است request.path .
  • بازی کامل: path الگوی منطبق کل request.path .

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

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

 // Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
  // Partial match.
  match /example/{singleSegment} {   // `singleSegment` == 'hello'
    allow write;                     // Write rule not evaluated.
    // Complete match.
    match /nested/path {             // `singleSegment` visible in scope.
      allow read;                    // Read rule is evaluated.
    }
  }
  // Complete match.
  match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
    allow read;                      // Read rule is evaluated.
  }
}
 

همانطور که مثال بالا نشان می دهد ، اعلامیه های path متغیرهای زیر را پشتیبانی می کند:

  • wildcard single-part: یک متغیر wildcard در یک مسیر با پیچیدن متغیر در بندهای فرفری اعلام می شود: {variable} . این متغیر در متن match به عنوان یک string قابل دسترسی است.
  • کارت ویزیت بازگشتی: علامت بازگشتی یا چند قسمتی ، wildcard با بخشهای مختلف مسیر در یا زیر یک مسیر مطابقت دارد. این کارت ویزیت با تمام مسیرهای زیر محلی که آن را تنظیم کرده اید مطابقت دارد. می توانید آن را با اضافه کردن رشته =** در انتهای متغیر بخش خود اعلام کنید: {variable=**} . این متغیر در جمله match به عنوان یک شی path قابل دسترسی است.

اجازه

بلوک match شامل یک یا چند بیانیه allow است. این قوانین واقعی شما هستند. شما می توانید درخواست allow به یک یا چند روش قوانین. شرایط موجود در بیانیه allow باید برای Cloud Firestore یا Storage برای تأیید هرگونه درخواست ورودی صحیح ارزیابی شود. شما همچنین می توانید بیانیه های allow را بدون شرایط بنویسید ، به عنوان مثال ، allow read . اگر بیانیه allow یک شرط را شامل نشود ، همیشه درخواست آن روش را مجاز می سازد.

در صورت رضایت هر یک از قوانین allow برای این روش ، درخواست مجاز است. علاوه بر این ، اگر یک قانون گسترده تر به شما دسترسی می دهد ، قوانین دسترسی را اجازه می دهند و هرگونه قوانین گرانوله تر که ممکن است دسترسی را محدود کند ، چشم پوشی می کنند.

مثال زیر را در نظر بگیرید ، جایی که هر کاربر می تواند هر یک از پرونده های خود را بخواند یا حذف کند. یک قانون گرانوله تر فقط اجازه می دهد تا کاربر درخواست کننده نوشتن پرونده را داشته باشد و پرونده آن PNG است. یک کاربر می تواند هر پرونده را در زیرگذر - حتی اگر آنها PNG نباشند - حذف کند زیرا قانون قبلی این اجازه را می دهد.

 service firebase.storage {
  // Allow the requestor to read or delete any resource on a path under the
  // user directory.
  match /users/{userId}/{anyUserFile=**} {
    allow read, delete: if request.auth != null && request.auth.uid == userId;
  }

  // Allow the requestor to create or update their own images.
  // When 'request.method' == 'delete' this rule and the one matching
  // any path under the user directory would both match and the `delete`
  // would be permitted.

  match /users/{userId}/images/{imageId} {
    // Whether to permit the request depends on the logical OR of all
    // matched rules. This means that even if this rule did not explicitly
    // allow the 'delete' the earlier rule would have.
    allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
  }
}
 

روش

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

روش نوع درخواست
روشهای راحتی
read هر نوع درخواست خوانده شده
write هر نوع درخواست نوشتن
روشهای استاندارد
get درخواست های مربوط به اسناد یا پرونده های واحد را بخوانید
list درخواست های نمایش داده شد و مجموعه ها را بخوانید
create اسناد یا پرونده های جدید بنویسید
update برای اسناد یا پرونده های موجود بنویسید
delete حذف داده ها

شما نمی توانید روشهای خواندن را در همان بلوک match یا روشهای نوشتن متناقض در بیانیه همان path همپوشانی کنید.

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

 service bad.example {
  match /rules/with/overlapping/methods {
    // This rule allows reads to all unauthenticated users
    allow read: if request.auth != null;

    match another/subpath {
      // This secondary, more specific read rule causes an error
      allow get: if request.auth != null && request.auth.uid == "me";
      // Overlapping write methods in the same path cause an error as well
      allow write: if request.auth != null;
      allow create: if request.auth != null && request.auth.uid == "me";
    }
  }
}
 

تابع

با پیچیده تر شدن قوانین امنیتی ، ممکن است بخواهید مجموعه ای از شرایط را در کارکردهایی بپیچید که می توانید از مجدداً استفاده کنید. قوانین امنیتی از توابع سفارشی پشتیبانی می کنند. نحو عملکردهای سفارشی کمی شبیه JavaScript است ، اما توابع قوانین امنیتی به زبانی خاص دامنه نوشته شده است که دارای برخی محدودیت های مهم است:

  • توابع فقط می توانند یک جمله return . آنها نمی توانند منطق دیگری داشته باشند. به عنوان مثال ، آنها نمی توانند حلقه ها را اجرا کنند یا با خدمات خارجی تماس بگیرند.
  • توابع می توانند به طور خودکار به توابع و متغیرهایی از محدوده ای که در آن تعریف شده است دسترسی پیدا کنند. به عنوان مثال ، تابعی که در محدوده service cloud.firestore تعریف شده باشد ، به متغیر resource و توابع داخلی مانند get() و exists() .
  • توابع ممکن است توابع دیگری را فراخوانی کنند ، اما ممکن است دوباره بازیابی نشوند. عمق تماس پشته فراخوان به 20 محدود است.
  • در قوانین نسخه v2 ، توابع می توانند متغیرها را با استفاده از کلید واژه let تعریف کنند. توابع می توانند حداکثر 10 اجازه اتصال داشته باشند ، اما باید با بیانیه بازگشت پایان یابد.

یک تابع با کلمه کلیدی function تعریف می شود و آرگومان های صفر یا بیشتر طول می کشد. به عنوان مثال ، ممکن است بخواهید دو نوع شرط استفاده شده در مثالهای فوق را با یک عملکرد واحد ترکیب کنید:

 service cloud.firestore {
  match /databases/{database}/documents {
    // True if the user is signed in or the requested data is 'public'
    function signedInOrPublic() {
      return request.auth.uid != null || resource.data.visibility == 'public';
    }

    match /cities/{city} {
      allow read, write: if signedInOrPublic();
    }

    match /users/{user} {
      allow read, write: if signedInOrPublic();
    }
  }
}
 

در اینجا مثالی وجود دارد که آرگومانهای عملکرد را نشان می دهد و به تکالیف اجازه می دهد. بگذارید بیانیه های واگذاری باید با نیم ستون ها جدا شوند.

 function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
  return isAuthor || isAdmin;
}

 

توجه داشته باشید که چگونه تکلیف isAdmin جستجوی مجموعه سرپرستها را افزایش می دهد. برای ارزیابی تنبلی و بدون نیاز به جستجوی غیر ضروری ، از ماهیت اتصال کوتاه && (AND) و || (یا) مقایسه برای تماس با یک تابع دوم فقط در صورتی که isAuthor نشان داده شود درست است (برای && مقایسه) یا نادرست (برای || مقایسه).

 function isAdmin(userId) {
  return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  // `||` is short-circuiting; isAdmin called only if isAuthor == false.
  return isAuthor || isAdmin(userId);
}
 

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

بانک اطلاعات املاک و مستغلات

همانطور که در بالا ذکر شد ، قوانین بانک اطلاعاتی Realtime شامل سه عنصر اساسی است: مکان پایگاه داده به عنوان آینه ساختار JSON بانک اطلاعاتی ، نوع درخواست و شرایط دسترسی.

محل پایگاه داده

ساختار قوانین شما باید از ساختار داده هایی که در پایگاه داده خود ذخیره کرده اید ، پیروی کند. به عنوان مثال ، در یک برنامه گپ با لیستی از پیام ها ، ممکن است داده هایی داشته باشید که به این صورت باشد:

   {
    "messages": {
      "message0": {
        "content": "Hello",
        "timestamp": 1405704370369
      },
      "message1": {
        "content": "Goodbye",
        "timestamp": 1405704395231
      },
      ...
    }
  }
 

قوانین شما باید از آن ساختار آینه داشته باشند. مثلا:

   {
    "rules": {
      "messages": {
        "$message": {
          // only messages from the last ten minutes can be read
          ".read": "data.child('timestamp').val() > (now - 600000)",

          // new messages must have a string content and a number timestamp
          ".validate": "newData.hasChildren(['content', 'timestamp']) &&
                        newData.child('content').isString() &&
                        newData.child('timestamp').isNumber()"
        }
      }
    }
  }
 

همانطور که در مثال بالا نشان داده شده است ، قوانین پایگاه داده Realtime از یک متغیر $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 }
      }
    }
  }
 

روش

در بانک اطلاعات Realtime ، سه نوع قانون وجود دارد. دو نوع از این قانون - read و write - در روش درخواست دریافتی اعمال می شوند. نوع قانون validate سازه های داده را تقویت کرده و قالب و محتوای داده ها را تأیید می کند. قوانین اجرا .validate پس از تایید که قوانین .write قانون دسترسی اعطا می کند.

انواع قانون
.خواندن توصیف می کند که داده ها چه موقع و توسط کاربران خوانده می شوند.
.نوشتن توصیف می کند که داده ها چه موقع مجاز به نوشتن هستند.
.تایید اعتبار تعریف می کند که یک مقدار به درستی فرمت شده ، چه ویژگی های کودک ، و چه نوع داده را نشان می دهد.

به طور پیش فرض ، اگر قانونی وجود ندارد که به آن اجازه دهد ، دسترسی به یک مسیر ممنوع است.

شرایط ساختمان

Cloud Firestore

شرط یک عبارت boolean است که تعیین می کند یک عمل خاص باید مجاز باشد یا رد می شود. متغیرهای request و resource زمینه این شرایط را فراهم می کنند.

متغیر request

متغیر request شامل قسمتهای زیر و اطلاعات مربوطه می باشد:

request.auth

توکن وب JSON (JWT) که حاوی اعتبار احراز هویت از تأیید اعتبار Firebase است. توکن auth شامل مجموعه ای از ادعاهای استاندارد و هرگونه ادعای سفارشی است که از طریق تأیید اعتبار Firebase ایجاد می کنید. درباره قوانین امنیتی و تأیید اعتبار Firebase بیشتر بدانید.

request.method

request.method ممکن است هر یک از روش های استاندارد و یا یک روش سفارشی. روشهای راحتی read و write نیز برای ساده کردن قوانین نوشتن وجود دارد که به ترتیب برای کلیه روشهای استاندارد فقط نوشتن یا همه نوشتن اعمال می شود.

request.params

request.params شامل هر گونه اطلاعات به طور خاص به مربوط نیست request.resource که ممکن است برای ارزیابی مفید است. در عمل ، این نقشه برای کلیه روشهای استاندارد خالی است و برای روشهای سفارشی باید حاوی داده های غیر منبع باشد. خدمات باید مراقب باشند از تغییر نام یا تغییر نوع هر یک از کلیدها و مقادیر ارائه شده به عنوان پارامتر جلوگیری شود.

request.path

request.path راه را برای هدف است resource . مسیر نسبت به سرویس است. بخش مسیر حاوی غیر URL شخصیت امن مانند / می کدگذاری شده url.

متغیر resource

resource مقدار فعلی موجود در سرویس است که به عنوان نقشه جفت های ارزش کلیدی نشان داده شده است. ارجاع resource در یک شرط منجر به خواندن حداقل یک مقدار از ارزش سرویس خواهد شد. این جست و جو در برابر هر سهمیه مربوط به سرویس برای منبع حساب خواهد شد. برای get درخواست ، این resource صرفاً در رد کردن سهمیه حساب خواهد شد.

تقسیم اپراتورها و اولویت ها

از جدول زیر به عنوان مرجع برای اپراتورها و اولویت مربوط به آنها در قوانین Cloud Firestore و Storage استفاده کنید.

با توجه به عبارات دلخواه a و b ، فیلد f و index i .

اپراتور شرح مشارکت
a[i] a() af فهرست ، تماس ، دسترسی به زمینه چپ به راست
!a -a نفی غیره راست به چپ
a/ba%ba*b اپراتورهای ضرب چپ به راست
a+b ab عملگرهای افزودنی چپ به راست
a>b a>=b a<b a<=b اپراتورهای ارتباطی چپ به راست
a in b ، a is b وجود لیست یا نقشه ، مقایسه نوع چپ به راست
a==ba!=b عملگرهای مقایسه چپ به راست
a && b مشروط و چپ به راست
a || b مشروط یا چپ به راست
a ? true_value : false_value بیان سه گانه چپ به راست

فضای ذخیره ابری

شرط یک عبارت boolean است که تعیین می کند یک عمل خاص باید مجاز باشد یا رد می شود. متغیرهای request و resource زمینه این شرایط را فراهم می کنند.

متغیر request

متغیر request شامل قسمتهای زیر و اطلاعات مربوطه می باشد:

request.auth

توکن وب JSON (JWT) که حاوی اعتبار احراز هویت از تأیید اعتبار Firebase است. توکن auth شامل مجموعه ای از ادعاهای استاندارد و هرگونه ادعای سفارشی است که از طریق تأیید اعتبار Firebase ایجاد می کنید. درباره قوانین امنیتی و تأیید اعتبار Firebase بیشتر بدانید.

request.method

request.method ممکن است هر یک از روش های استاندارد و یا یک روش سفارشی. روشهای راحتی read و write نیز برای ساده کردن قوانین نوشتن وجود دارد که به ترتیب برای کلیه روشهای استاندارد فقط نوشتن یا همه نوشتن اعمال می شود.

request.params

request.params شامل هر گونه اطلاعات به طور خاص به مربوط نیست request.resource که ممکن است برای ارزیابی مفید است. در عمل ، این نقشه برای کلیه روشهای استاندارد خالی است و برای روشهای سفارشی باید حاوی داده های غیر منبع باشد. خدمات باید مراقب باشند از تغییر نام یا تغییر نوع هر یک از کلیدها و مقادیر ارائه شده به عنوان پارامتر جلوگیری شود.

request.path

request.path راه را برای هدف است resource . مسیر نسبت به سرویس است. بخش مسیر حاوی غیر URL شخصیت امن مانند / می کدگذاری شده url.

متغیر resource

resource مقدار فعلی موجود در سرویس است که به عنوان نقشه جفت های ارزش کلیدی نشان داده شده است. ارجاع resource در یک شرط منجر به خواندن حداقل یک مقدار از ارزش سرویس خواهد شد. این جست و جو در برابر هر سهمیه مربوط به سرویس برای منبع حساب خواهد شد. برای get درخواست ، این resource صرفاً در رد کردن سهمیه حساب خواهد شد.

تقسیم اپراتورها و اولویت ها

از جدول زیر به عنوان مرجع برای اپراتورها و اولویت مربوط به آنها در قوانین Cloud Firestore و Storage استفاده کنید.

با توجه به عبارات دلخواه a و b ، فیلد f و index i .

اپراتور شرح مشارکت
a[i] a() af فهرست ، تماس ، دسترسی به زمینه چپ به راست
!a -a نفی غیره راست به چپ
a/ba%ba*b اپراتورهای ضرب چپ به راست
a+b ab عملگرهای افزودنی چپ به راست
a>b a>=b a<b a<=b اپراتورهای ارتباطی چپ به راست
a in b ، a is b وجود لیست یا نقشه ، مقایسه نوع چپ به راست
a==ba!=b عملگرهای مقایسه چپ به راست
a && b مشروط و چپ به راست
a || b مشروط یا چپ به راست
a ? true_value : false_value بیان سه گانه چپ به راست

بانک اطلاعات املاک و مستغلات

شرط یک عبارت boolean است که تعیین می کند یک عمل خاص باید مجاز باشد یا رد می شود. شما می توانید آن شرایط را در قوانین پایگاه داده Realtime به روش های زیر تعریف کنید.

متغیرهای از پیش تعریف شده

تعدادی متغیر مفید ، از پیش تعریف شده وجود دارد که می توان در یک تعریف قانون به آنها دسترسی داشت. در اینجا مختصراً از هریک آورده شده است:

متغیرهای از پیش تعریف شده
اکنون زمان کنونی در میلی ثانیه از دوران لینوکس. این امر به ویژه برای تأیید اعتبارسنجهای زمانی ایجاد شده با SDK's firebase.database.ServerValue.TIMESTAMP خوب عمل می کند.
ریشه RuleDataSnapshot نمایانگر مسیر ریشه در پایگاه داده Firebase همانطور که قبل از عمل تلاش می شود.
newData RuleDataSnapshot که داده ها را نشان می دهد همانطور که می توان پس از انجام عملیات وجود داشت. این شامل داده های جدید نوشته شده و داده های موجود است.
داده ها RuleDataSnapshot داده های موجود را قبل از اجرای عملیات نشان می دهد.
متغیرهای $ یک مسیر wildcard که برای نشان دادن شناسه ها و کلیدهای کودک پویا استفاده می شود.
نویسنده بارگذاری رمز معتبر کاربر را نشان می دهد.

این متغیرها می توانند در هر نقطه از قوانین شما استفاده شوند. به عنوان مثال ، قوانین امنیتی زیر اطمینان می دهند که داده های نوشته شده برای /foo/ گره باید رشته ای کمتر از 100 نویسه باشند:

{
  "rules": {
    "foo": {
      // /foo is readable by the world
      ".read": true,

      // /foo is writable by the world
      ".write": true,

      // data written to /foo must be a string less than 100 characters
      ".validate": "newData.isString() && newData.val().length < 100"
    }
  }
}

قوانین مبتنی بر داده

از داده های موجود در بانک اطلاعاتی خود می توانید در قوانین خود استفاده کنید. با استفاده از root ، data و newData متغیرهای از پیش تعریف شده ، می توانید به هر مسیری دسترسی پیدا کنید که قبل یا بعد از یک رویداد نوشتن وجود داشته باشد.

این مثال را در نظر بگیرید ، که اجازه می دهد تا عملیات نوشتن را تا زمانی که ارزش /allow_writes/ readOnly /allow_writes/ گره true ، گره والد دارای یک مجموعه پرچم readOnly ، و در داده های تازه نوشته شده کودکی بنام foo وجود دارد:

".write": "root.child('allow_writes').val() === true &&
          !data.parent().child('readOnly').exists() &&
          newData.child('foo').exists()"

قوانین مبتنی بر پرس و جو

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

به عنوان مثال ، قانون مبتنی بر پرس و جو زیر از قوانین امنیتی مبتنی بر کاربر و قوانین مبتنی بر پرس و جو برای محدود کردن دسترسی به داده ها در مجموعه baskets ها فقط به سبدهای خرید کاربر فعال استفاده می کند:

 "baskets": {
  ".read": "auth.uid != null &&
            query.orderByChild == 'owner' &&
            query.equalTo == auth.uid" // restrict basket access to owner of basket
}
 

عبارت زیر که شامل پارامترهای پرس و جو در قاعده است ، موفق می شود:

 db.ref("baskets").orderByChild("owner")
                 .equalTo(auth.currentUser.uid)
                 .on("value", cb)                 // Would succeed
 

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

 db.ref("baskets").on("value", cb)                 // Would fail with PermissionDenied
 

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

به عنوان مثال ، قانون زیر دسترسی خواندن فقط به 1000 نتیجه اول پرس و جو را طبق دستور اولویت محدود می کند:

 messages: {
  ".read": "query.orderByKey &&
            query.limitToFirst <= 1000"
}

// Example queries:

db.ref("messages").on("value", cb)                // Would fail with PermissionDenied

db.ref("messages").limitToFirst(1000)
                  .on("value", cb)                // Would succeed (default order by key)

 

query. زیر عبارات در قوانین بانک اطلاعات Realtime موجود است.

عبارات قانون مبتنی بر پرس و جو
اصطلاح تایپ کنید شرح
query.orderByKey
query.orderByPriority
query.orderByValue
بول برای جستجوی نمایش داده شده توسط کلید ، اولویت یا مقدار صحیح است. در غیر این صورت دروغین
query.orderByChild رشته
خالی
از یک رشته برای نشان دادن مسیر نسبی گره کودک استفاده کنید. به عنوان مثال ، query.orderByChild == "address/zip" . اگر درخواست توسط گره کودک سفارش داده نشده باشد ، این مقدار تهی نیست.
query.startAt
پرس و جو کنید
query. EqualTo
رشته
عدد
بول
خالی
مرزهای درخواست اجرای را بازیابی می کند ، یا در صورت عدم وجود مجموعه محدود ، تهی برمی گرداند.
query.limitToFirst
query.limitToLast
عدد
خالی
مقدار درخواست مربوط به اجرای برنامه را بازیابی می کند یا در صورت عدم تعیین حد مجاز ، تهی برمی گرداند.

عملگرها

قوانین پایگاه داده Realtime تعدادی از اپراتورهایی را که می توانید برای ترکیب متغیرها در بیانیه شرط استفاده کنید ، پشتیبانی می کند. لیست کامل اپراتورها را در مستندات مرجع مشاهده کنید .

ایجاد شرایط

شرایط واقعی شما بسته به دستیابی که می خواهید اعطا کنید متفاوت خواهد بود. قوانین عمدا انعطاف پذیری بسیار زیادی را ارائه می دهند ، بنابراین قوانین برنامه شما در نهایت می توانند به همان اندازه ساده یا پیچیده ای باشند که برای آنها لازم است.

برای ایجاد راهنمایی در ایجاد قوانین ساده و آماده ، به قوانین اساسی امنیتی مراجعه کنید.