این راهنما مبتنی بر یادگیری نحو اصلی راهنمای زبان Firebase Security Rules تا نحوه افزودن شرایط به Firebase Security Rules برای Cloud Storage را نشان دهد.
بلوک اصلی ساختمان Cloud Storage Security Rules شرط است. شرط یک عبارت بولی است که تعیین می کند آیا یک عملیات خاص باید مجاز یا رد شود. برای قوانین اساسی، استفاده از لفظ های true
و false
به عنوان شرایط کاملاً خوب عمل می کند. اما Firebase Security Rules برای زبان Cloud Storage راه هایی را برای نوشتن شرایط پیچیده تری به شما ارائه می دهد که می تواند:
- احراز هویت کاربر را بررسی کنید
- اعتبار سنجی داده های دریافتی
احراز هویت
Firebase Security Rules برای Cloud Storage با Firebase Authentication ادغام می شود تا احراز هویت قدرتمند مبتنی بر کاربر را برای Cloud Storage فراهم کند. این امکان کنترل دسترسی گرانول را بر اساس ادعاهای یک نشانه Firebase Authentication فراهم می کند.
وقتی یک کاربر احراز هویت درخواستی را علیه Cloud Storage انجام میدهد، متغیر request.auth
با uid
کاربر ( request.auth.uid
) و همچنین ادعاهای Firebase Authentication JWT ( request.auth.token
) پر میشود.
علاوه بر این، هنگام استفاده از احراز هویت سفارشی، ادعاهای اضافی در قسمت request.auth.token
ظاهر می شود.
هنگامی که یک کاربر احراز هویت نشده درخواستی را انجام می دهد، متغیر request.auth
null
است.
با استفاده از این داده ها، چندین روش رایج برای استفاده از احراز هویت برای ایمن سازی فایل ها وجود دارد:
- عمومی: نادیده گرفتن
request.auth
- خصوصی تأیید شده: بررسی کنید که
request.auth
null
نیست - کاربر خصوصی: بررسی کنید که
request.auth.uid
برابر باuid
مسیر باشد - گروه خصوصی: ادعاهای نشانه سفارشی را بررسی کنید تا با ادعای انتخابی مطابقت داشته باشد، یا فراداده فایل را بخوانید تا ببینید آیا یک قسمت فراداده وجود دارد یا خیر.
عمومی
هر قانونی که زمینه request.auth
را در نظر نگیرد، میتواند یک قانون public
در نظر گرفته شود، زیرا زمینه احراز هویت کاربر را در نظر نمیگیرد. این قوانین میتواند برای نمایش دادههای عمومی مانند داراییهای بازی، فایلهای صوتی یا سایر محتوای ثابت مفید باشد.
// Anyone to read a public image if the file is less than 100kB // Anyone can upload a public file ending in '.txt' match /public/{imageId} { allow read: if resource.size < 100 * 1024; allow write: if imageId.matches(".*\\.txt"); }
خصوصی تایید شده
در موارد خاص، ممکن است بخواهید داده ها توسط همه کاربران احراز هویت شده برنامه شما قابل مشاهده باشد، اما توسط کاربران احراز هویت نشده قابل مشاهده نباشد. از آنجایی که متغیر request.auth
برای همه کاربران احراز هویت نشده null
است، تنها کاری که باید انجام دهید این است که وجود متغیر request.auth
را بررسی کنید تا به احراز هویت نیاز داشته باشید:
// Require authentication on all internal image reads match /internal/{imageId} { allow read: if request.auth != null; }
کاربر خصوصی
تا حد زیادی رایج ترین مورد استفاده برای request.auth
ارائه مجوزهای جزئی به کاربران در فایل هایشان است: از آپلود تصاویر نمایه تا خواندن اسناد خصوصی.
از آنجایی که فایلهای موجود در Cloud Storage دارای یک «مسیر» کامل به فایل هستند، تنها چیزی که لازم است برای ایجاد فایلی که توسط کاربر کنترل میشود، تکهای از اطلاعات شناسایی منحصربهفرد کاربر در پیشوند نام فایل (مانند uid
کاربر) است که میتوان آن را بررسی کرد. هنگامی که قانون ارزیابی می شود:
// Only a user can upload their profile picture, but anyone can view it match /users/{userId}/profilePicture.png { allow read; allow write: if request.auth.uid == userId; }
گروه خصوصی
یکی دیگر از موارد استفاده به همان اندازه رایج، اجازه دادن مجوزهای گروه بر روی یک شی است، مانند اجازه دادن به چندین عضو تیم برای همکاری در یک سند مشترک. چندین روش برای انجام این کار وجود دارد:
- یک توکن سفارشی Firebase Authentication که حاوی اطلاعات اضافی در مورد یکی از اعضای گروه (مانند شناسه گروه) است، ایجاد کنید.
- شامل اطلاعات گروه (مانند شناسه گروه یا لیستی از
uid
های مجاز) در فراداده فایل
هنگامی که این داده ها در فراداده توکن یا فایل ذخیره می شوند، می توان از داخل یک قانون به آن ارجاع داد:
// 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; }
درخواست ارزیابی
بارگذاریها، بارگیریها، تغییرات فراداده، و حذفها با استفاده از request
ارسال شده به Cloud Storage ارزیابی میشوند. علاوه بر شناسه منحصر به فرد کاربر و بارگذاری Firebase Authentication در شی request.auth
همانطور که در بالا توضیح داده شد، متغیر request
شامل مسیر فایلی است که درخواست در آن انجام می شود، زمان دریافت درخواست و مقدار resource
جدید در صورتی که درخواست نوشتن است
شی 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 | رشته | تگ مرتبط با این شی. |
contentDisposition | رشته | محتوای محتوای مرتبط با این شی. |
contentEncoding | رشته | رمزگذاری محتوای مرتبط با این شی. |
contentLanguage | رشته | زبان محتوای مرتبط با این شی. |
contentType | رشته | نوع محتوای مرتبط با این شی. |
metadata | نقشه<رشته، رشته> | جفت کلید/مقدار متادیتای سفارشی اضافی و مشخص شده توسط توسعه دهنده. |
request.resource
شامل همه اینها به استثنای generation
, metageneration
, etag
, timeCreated
و updated
.
با Cloud Firestore تقویت کنید
برای ارزیابی سایر معیارهای مجوز می توانید به اسناد موجود در Cloud Firestore دسترسی داشته باشید.
با استفاده از توابع firestore.get()
و firestore.exists()
، قوانین امنیتی شما می توانند درخواست های دریافتی را در برابر اسناد موجود در Cloud Firestore ارزیابی کنند. توابع firestore.get()
و firestore.exists()
هر دو انتظار مسیرهای سند کاملاً مشخص را دارند. هنگام استفاده از متغیرها برای ساخت مسیرهایی برای firestore.get()
و firestore.exists()
، باید به طور صریح از متغیرها با استفاده از دستور $(variable)
فرار کنید.
در مثال زیر، قانونی را مشاهده میکنیم که دسترسی خواندن به فایلها را برای کاربرانی که عضو باشگاههای خاصی هستند، محدود میکند.
service firebase.storage { match /b/{bucket}/o { match /users/{club}/files/{fileId} { allow read: if club in firestore.get(/databases/(default)/documents/users/$(request.auth.id)).memberships } } }در مثال بعدی فقط دوستان یک کاربر می توانند عکس های او را ببینند.
service firebase.storage { match /b/{bucket}/o { match /users/{userId}/photos/{fileId} { allow read: if firestore.exists(/databases/(default)/documents/users/$(userId)/friends/$(request.auth.id)) } } }
پس از ایجاد و ذخیره اولین Cloud Storage Security Rules خود که از این توابع Cloud Firestore استفاده میکنند، در کنسول Firebase یا Firebase CLI از شما خواسته میشود تا مجوزهای اتصال دو محصول را فعال کنید.
همانطور که در Manage and Deploy Firebase Security Rules توضیح داده شده است، میتوانید این ویژگی را با حذف یک نقش IAM غیرفعال کنید.
اعتبارسنجی داده ها
Firebase Security Rules برای Cloud Storage همچنین میتواند برای اعتبارسنجی دادهها، از جمله اعتبارسنجی نام فایل و مسیر و همچنین ویژگیهای فراداده فایل مانند contentType
و size
استفاده شود.
service firebase.storage { match /b/{bucket}/o { match /images/{imageId} { // Only allow uploads of any image file that's less than 5MB allow write: if request.resource.size < 5 * 1024 * 1024 && request.resource.contentType.matches('image/.*'); } } }
توابع سفارشی
همانطور که Firebase Security Rules شما پیچیده تر می شوند، ممکن است بخواهید مجموعه ای از شرایط را در توابعی قرار دهید که بتوانید در سراسر مجموعه قوانین خود دوباره از آنها استفاده کنید. قوانین امنیتی از توابع سفارشی پشتیبانی می کنند. سینتکس توابع سفارشی کمی شبیه جاوا اسکریپت است، اما توابع Firebase Security Rules در یک زبان مخصوص دامنه نوشته شدهاند که محدودیتهای مهمی دارد:
- توابع می توانند تنها حاوی یک عبارت
return
باشند. آنها نمی توانند حاوی هیچ منطق اضافی باشند. به عنوان مثال، آنها نمی توانند حلقه ها را اجرا کنند یا خدمات خارجی را فراخوانی کنند. - توابع می توانند به طور خودکار به توابع و متغیرها از محدوده ای که در آن تعریف شده اند دسترسی داشته باشند. به عنوان مثال، یک تابع تعریف شده در محدوده
service firebase.storage
به متغیرresource
دسترسی دارد و فقط برای Cloud Firestore ، توابع داخلی مانندget()
وexists()
. - توابع ممکن است توابع دیگر را فراخوانی کنند اما ممکن است تکرار نشوند. کل عمق پشته تماس به 10 محدود شده است.
- در
rules2
نسخه2، توابع می توانند متغیرها را با استفاده از کلمه کلیدیlet
تعریف کنند. توابع می توانند هر تعداد اتصال let داشته باشند، اما باید با یک عبارت return پایان یابند.
یک تابع با کلمه کلیدی function
تعریف می شود و صفر یا بیشتر آرگومان می گیرد. برای مثال، ممکن است بخواهید دو نوع شرط استفاده شده در مثال های بالا را در یک تابع واحد ترکیب کنید:
service firebase.storage {
match /b/{bucket}/o {
// 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 /images/{imageId} {
allow read, write: if signedInOrPublic();
}
match /mp3s/{mp3Ids} {
allow read: if signedInOrPublic();
}
}
}
استفاده از توابع در Firebase Security Rules باعث میشود که با افزایش پیچیدگی قوانین شما، آنها را نگهدارید.
مراحل بعدی
پس از این بحث در مورد شرایط، شما درک پیچیده تری از قوانین دارید و آماده هستید:
نحوه رسیدگی به موارد استفاده اصلی را بیاموزید و گردش کار برای توسعه، آزمایش و استقرار قوانین را بیاموزید:
- قوانینی بنویسید که به سناریوهای رایج رسیدگی می کنند.
- با مرور موقعیت هایی که باید قوانین ناامن را شناسایی کرده و از آن اجتناب کنید ، دانش خود را تقویت کنید.
- قوانین را با استفاده از شبیه ساز Cloud Storage و کتابخانه آزمایشی اختصاصی قوانین امنیتی آزمایش کنید.
- روش های موجود برای استقرار Rules مرور کنید.