استفاده از شرایط در «قوانین امنیتی فضای ذخیره‌سازی ابری Firebase»

این راهنما براساس راهنمای آشنایی با نحو اصلی زبان Firebase Security Rules ساخته شده است تا نحوه افزودن شرایط به Firebase Security Rules برای Cloud Storage را نشان دهد.

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

  • بررسی اصالت‌سنجی کاربر
  • اعتبارسنجی داده‌های ورودی

برای کمک هوش مصنوعی، پیام‌واره زیر را در عامل کدنویسی هوش مصنوعی خود (مانند Gemini در Android Studio،‏ Antigravity،‏ Claude Code،‏ Codex، و Cursor) کپی کنید. می‌توانید پیام‌واره را سفارشی‌سازی کنید و با عاملتان تکرار کنید. برای اطلاعات دقیق نصب، به مهارت‌های عامل Firebase مراجعه کنید.

Help me use Firebase in my app.
1. Make sure that **Firebase agent skills** are installed and updated. For Claude Code, Codex, or Cursor agents, help me install the Firebase plugin. For other agents, run `npx skills add firebase/agent-skills`. Always try to use **Firebase agent skills** for Firebase-related tasks.
2. Help me write, validate, and deploy Firebase Security Rules to protect my app's Cloud Storage data.

اصالت‌سنجی

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 map<string, string> وقتی کاربر به سیستم وارد شده باشد، uid، شناسه یکتای کاربر، و token، نقشه‌ای از ادعاهای JWT Firebase Authentication را ارائه می‌دهد. درغیراین‌صورت، null خواهد بود.
params map<string, string> نقشه‌ای که حاوی پارامترهای پُرسمان درخواست است.
path مسیر path نشان‌دهنده مسیری است که درخواست در آن اجرا می‌شود.
resource map<string, string> مقدار منبع جدید، فقط در درخواست‌های 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 map<string, string> جفت‌های کلید/مقدار فراداده سفارشی اضافی که توسعه‌دهنده مشخص کرده است.

‫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)).data.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 از شما خواسته می‌شود اجازه‌های اتصال دو محصول را فعال کنید.

می‌توانید این ویژگی را با برداشتن نقش IAM غیرفعال کنید، همان‌طور که در مدیریت و استقرار Firebase Security Rules شرح داده شده است.

اعتبارسنجی داده‌ها

‫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().
  • توابع ممکن است توابع دیگر را فراخوانی کنند اما ممکن است بازگشتی نباشند. عمق کل پشته فراخوانی به ۱۰ محدود است.
  • در نسخه rules2، توابع می‌توانند متغیرها را بااستفاده از کلیدواژه 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 باعث می‌شود که با افزایش پیچیدگی قوانین، نگهداری آن‌ها آسان‌تر شود.

مراحل بعدی

پس‌از این بحث درباره شرایط، درک پیچیده‌تری از «قوانین» دارید و آماده‌اید:

با نحوه مدیریت موارد استفاده اصلی و گردش کار برای توسعه، آزمایش، و استقرار «قوانین» آشنا شوید: