سینتکس اصلی قوانین امنیتی Firebase برای زبان Cloud Storage را بیاموزید

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

این راهنما، سینتکس و ساختار اولیه‌ی Cloud Storage Security Rules را برای ایجاد مجموعه قوانین کامل شرح می‌دهد.

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

Firebase Security Rules برای Cloud Storage همیشه با عبارت زیر شروع می‌شوند:

service firebase.storage {
    // ...
}

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

قوانین اساسی خواندن/نوشتن

قوانین اساسی شامل یک عبارت match است که سطل‌های Cloud Storage را مشخص می‌کند، یک عبارت match که نام فایل را مشخص می‌کند و یک عبارت allow که جزئیات خواندن داده‌های مشخص شده را شرح می‌دهد. عبارات allow روش‌های دسترسی (مثلاً خواندن، نوشتن) مربوطه و شرایطی را که تحت آن دسترسی مجاز یا رد می‌شود، مشخص می‌کنند.

در مجموعه قوانین پیش‌فرض شما، اولین عبارت match از یک عبارت wildcard {bucket} استفاده می‌کند تا نشان دهد که قوانین برای همه bucketهای پروژه شما اعمال می‌شود. در بخش بعدی بیشتر در مورد ایده تطبیق wildcardها بحث خواهیم کرد.

service firebase.storage {
  // The {bucket} wildcard indicates we match files in all Cloud Storage buckets
  match /b/{bucket}/o {
    // Match filename
    match /filename {
      allow read: if <condition>;
      allow write: if <condition>;
    }
  }
}

همه دستورات match به فایل‌ها اشاره می‌کنند. یک دستور match می‌تواند به یک فایل خاص اشاره کند، مانند match /images/profilePhoto.png .

تطبیق وایلدکارت‌ها

علاوه بر اشاره به یک فایل واحد، Rules می‌توانند از کاراکترهای جایگزین (wildcards) برای اشاره به هر فایلی که پیشوند رشته‌ای مشخصی در نام آن وجود دارد، از جمله اسلش‌ها، استفاده کنند، مانند match /images/{imageId} .

در مثال بالا، دستور match از سینتکس wildcard {imageId} استفاده می‌کند. این بدان معناست که این قانون برای هر فایلی که در ابتدای نام آن /images/ قرار دارد، مانند /images/profilePhoto.png یا /images/croppedProfilePhoto.png ، اعمال می‌شود. هنگامی که عبارات allow در دستور match ارزیابی می‌شوند، متغیر imageId به نام فایل تصویر، مانند profilePhoto.png یا croppedProfilePhoto.png ، تبدیل می‌شود.

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

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

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

همانطور که قبلاً گفتیم، هیچ ساختار سلسله مراتبی درون یک مخزن Cloud Storage وجود ندارد. اما با استفاده از یک قرارداد نامگذاری فایل، که اغلب شامل اسلش در نام فایل‌ها می‌شود، می‌توانیم ساختاری را تقلید کنیم که شبیه مجموعه‌ای تو در تو از دایرکتوری‌ها و زیر دایرکتوری‌ها باشد. درک نحوه تعامل Firebase Security Rules با این نام فایل‌ها مهم است.

وضعیت مجموعه‌ای از فایل‌ها را در نظر بگیرید که نام همه آنها با /images/ ‎ شروع می‌شود. Firebase Security Rules فقط در نام فایل منطبق اعمال می‌شوند، بنابراین کنترل‌های دسترسی تعریف شده در /images/ ‎ به /mp3s/ ‎ اعمال نمی‌شوند. در عوض، قوانین صریحی بنویسید که با الگوهای نام فایل مختلف مطابقت داشته باشند:

service firebase.storage {
  match /b/{bucket}/o {
    match /images/{imageId} {
      allow read, write: if <condition>;
    }

    // Explicitly define rules for the 'mp3s' pattern
    match /mp3s/{mp3Id} {
      allow read, write: if <condition>;
    }
  }
}

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

service firebase.storage {
  match /b/{bucket}/o {
    match /images {
      // Exact match for "images/profilePhoto.png"
      match /profilePhoto.png {
        allow write: if <condition>;
      }
    }
  }
}
service firebase.storage {
  match /b/{bucket}/o {
    // Exact match for "images/profilePhoto.png"
    match /images/profilePhoto.png {
      allow write: if <condition>;
      }
  }
}

کاراکترهای جایگزین تطبیق بازگشتی

علاوه بر کاراکترهای جانشین (wildcards) که با رشته‌های انتهای نام فایل مطابقت دارند و آنها را برمی‌گردانند، می‌توان با اضافه کردن =** به نام کاراکتر جانشین، یک کاراکتر جانشین چند بخشی برای تطبیق‌های پیچیده‌تر تعریف کرد، مانند {path=**} :

// Partial match for files that start with "images"
match /images {

  // 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 است.

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

نسخه ۱

Firebase Security Rules به طور پیش‌فرض از نسخه ۱ استفاده می‌کنند. در نسخه ۱، کاراکترهای بازگشتی (recursive wildcards) با یک یا چند عنصر نام فایل مطابقت دارند، نه با صفر یا چند عنصر. بنابراین، match /images/{filenamePrefixWildcard}/{imageFilename=**} با نام فایلی مانند /images/profilePics/profile.png مطابقت دارد، اما با /images/badge.png مطابقت ندارد. به جای آن از /images/{imagePrefixorFilename=**} استفاده کنید.

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

توصیه می‌کنیم از نسخه ۲ استفاده کنید، چون امکانات بیشتری دارد.

نسخه ۲

در نسخه ۲ Firebase Security Rules ، کاراکترهای جایگزین بازگشتی با صفر یا چند مورد مسیر مطابقت دارند. بنابراین، /images/{filenamePrefixWildcard}/{imageFilename=**} با نام فایل‌های /images/profilePics/profile.png و /images/badge.png مطابقت دارد.

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

rules_version = '2';
service cloud.storage {
  match /b/{bucket}/o {
   ...
 }
}

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

rules_version = '2';
service firebase.storage {
 match /b/{bucket}/o {
   // Matches any file in a songs "subdirectory" under the
   // top level of your Cloud Storage bucket.
   match /{prefixSegment=**}/songs/{mp3filenames} {
     allow read, write: if <condition>;
   }
  }
}

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

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

یک عملیات read می‌تواند به دو بخش get و list تقسیم شود.

یک قانون write می‌تواند به create ، update و delete تقسیم شود:

service firebase.storage {
  match /b/{bucket}/o {
    // A read rule can be divided into read and list rules
    match /images/{imageId} {
      // Applies to single file read requests
      allow get: if <condition>;
      // Applies to list and listAll requests (Rules Version 2)
      allow list: if <condition>;

    // A write rule can be divided into create, update, and delete rules
    match /images/{imageId} {
      // Applies to writes to file contents
      allow create: if <condition>;

      // Applies to updates to (pre-existing) file metadata
      allow update: if <condition>;

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

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

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

service firebase.storage {
  match b/{bucket}/o {
    // Matches file names directly inside of '/images/'.
    match /images/{imageId} {
      allow read, write: if false;
    }

    // Matches file names anywhere under `/images/`
    match /images/{imageId=**} {
      allow read, write: if true;
    }
  }
}

در مثال بالا، تمام خواندن‌ها و نوشتن‌ها در فایل‌هایی که نام آنها با /images/ شروع می‌شود مجاز است زیرا قانون دوم همیشه true است، حتی زمانی که قانون اول false باشد.

قوانین فیلتر نیستند

وقتی داده‌های خود را ایمن کردید و شروع به انجام عملیات روی فایل‌ها کردید، به خاطر داشته باشید که قوانین امنیتی فیلتر نیستند. شما نمی‌توانید روی مجموعه‌ای از فایل‌ها که با الگوی نام فایل مطابقت دارند، عملیات انجام دهید و انتظار داشته باشید که Cloud Storage فقط به فایل‌هایی که کلاینت فعلی اجازه دسترسی به آنها را دارد، دسترسی داشته باشد.

برای مثال، قانون امنیتی زیر را در نظر بگیرید:

service firebase.storage {
  match /b/{bucket}/o {
    // Allow the client to read files with contentType 'image/png'
    match /aFileNamePrefix/{aFileName} {
      allow read: if resource.contentType == 'image/png';
    }
  }
}

رد شد : این قانون درخواست زیر را رد می‌کند زیرا مجموعه نتایج می‌تواند شامل فایل‌هایی باشد که contentType آنها image/png نیست:

وب
filesRef = storage.ref().child("aFilenamePrefix");

filesRef.listAll()
    .then(function(result) {
      console.log("Success: ", result.items);
    })
});

قوانین در Cloud Storage Security Rules هر پرس‌وجو را در برابر نتیجه‌ی احتمالی آن ارزیابی می‌کند و اگر درخواست بتواند فایلی را برگرداند که کلاینت اجازه‌ی خواندن آن را ندارد، آن را رد می‌کند. درخواست‌های دسترسی باید از محدودیت‌های تعیین‌شده توسط قوانین شما پیروی کنند.

مراحل بعدی

می‌توانید درک خود را از Firebase Security Rules برای Cloud Storage عمیق‌تر کنید:

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

  • موارد استفاده امنیتی معمول و تعاریف Firebase Security Rules که به آنها می‌پردازد را مرور کنید.

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