Check out what’s new from Firebase at Google I/O 2022. Learn more

استخدم الشروط في قواعد أمان Firebase Cloud Storage

يعتمد هذا الدليل على تعلم البنية الأساسية لدليل لغة قواعد أمان Firebase لإظهار كيفية إضافة شروط إلى قواعد أمان Firebase للتخزين السحابي.

العنصر الأساسي الأساسي لقواعد أمان التخزين السحابي هو الشرط . الشرط هو تعبير منطقي يحدد ما إذا كان يجب السماح بعملية معينة أو رفضها. بالنسبة للقواعد الأساسية ، فإن استخدام القيم true false كشرط يعمل بشكل جيد. لكن قواعد أمان Firebase للغة التخزين السحابي تمنحك طرقًا لكتابة شروط أكثر تعقيدًا يمكنها:

  • تحقق من مصادقة المستخدم
  • تحقق من صحة البيانات الواردة

المصادقة

تتكامل قواعد أمان Firebase للتخزين السحابي مع مصادقة Firebase لتوفير مصادقة قوية قائمة على المستخدم للتخزين السحابي. يسمح هذا بالتحكم الدقيق في الوصول استنادًا إلى مطالبات رمز مصادقة Firebase المميز.

عندما يقوم مستخدم مصدق عليه بتنفيذ طلب مقابل Cloud Storage ، يتم ملء متغير request.auth المستخدم ( request.auth.uid ) بالإضافة إلى مطالبات uid 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 يحتوي على معلومات إضافية حول أحد أعضاء المجموعة (مثل معرف المجموعة)
  • قم بتضمين معلومات المجموعة (مثل معرف المجموعة أو قائمة 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 في كائن request.auth كما هو موضح أعلاه ، يحتوي متغير request على مسار الملف حيث يتم تنفيذ الطلب ووقت استلام الطلب وقيمة resource الجديد إذا الطلب كتابة. يتم أيضًا تضمين رؤوس HTTP وحالة المصادقة.

يحتوي كائن request أيضًا على المعرف الفريد للمستخدم وحمولة مصادقة Firebase في كائن request.auth ، والذي سيتم شرحه بمزيد من التفصيل في قسم "الأمان المستند إلى المستخدم" في المستندات.

تتوفر قائمة كاملة بالخصائص في كائن request أدناه:

ملكية نوع وصف
auth الخريطة <سلسلة ، سلسلة> عندما يقوم المستخدم بتسجيل الدخول ، يقدم uid ، المعرف الفريد للمستخدم ، token ، خريطة لمطالبات Firebase Authentication JWT. خلاف ذلك ، سيكون null .
params الخريطة <سلسلة ، سلسلة> خريطة تحتوي على معامِلات طلب البحث للطلب.
path طريق path يمثل المسار الذي يتم تنفيذ الطلب فيه.
resource الخريطة <سلسلة ، سلسلة> قيمة المورد الجديد ، موجودة فقط في طلبات write .
time الطابع الزمني طابع زمني يمثل وقت تقييم الطلب على الخادم.

تقييم الموارد

عند تقييم القواعد ، قد ترغب أيضًا في تقييم البيانات الوصفية للملف الجاري تحميله أو تنزيله أو تعديله أو حذفه. يتيح لك ذلك إنشاء قواعد معقدة وقوية تقوم بأشياء مثل السماح فقط بتحميل الملفات ذات أنواع محتويات معينة ، أو حذف الملفات التي يزيد حجمها عن حجم معين فقط.

توفر قواعد أمان Firebase للتخزين السحابي بيانات وصفية للملف في كائن resource ، والتي تحتوي على أزواج مفتاح / قيمة من البيانات الوصفية التي تظهر في كائن التخزين السحابي. يمكن فحص هذه الخصائص في طلبات read أو write لضمان سلامة البيانات.

في طلبات write (مثل عمليات التحميل وتحديثات البيانات الوصفية والحذف) ، بالإضافة إلى كائن resource ، الذي يحتوي على بيانات تعريف الملف للملف الموجود حاليًا في مسار الطلب ، يمكنك أيضًا استخدام كائن request.resource ، الذي يحتوي على مجموعة فرعية من البيانات الوصفية للملف المراد كتابتها في حالة السماح بالكتابة. يمكنك استخدام هاتين القيمتين لضمان تكامل البيانات أو فرض قيود التطبيق مثل نوع الملف أو الحجم.

قائمة كاملة من الخصائص في كائن resource متاحة أدناه:

ملكية نوع وصف
name سلسلة الاسم الكامل للكائن
bucket سلسلة اسم المستودع الذي يتواجد فيه هذا الكائن.
generation int إنشاء كائن Google Cloud Storage لهذا الكائن.
metageneration int كائن Google Cloud Storage metageneration لهذا الكائن.
size int حجم الكائن بالبايت.
timeCreated الطابع الزمني طابع زمني يمثل الوقت الذي تم فيه إنشاء كائن.
updated الطابع الزمني طابع زمني يمثل وقت آخر تحديث للعنصر.
md5Hash سلسلة تجزئة MD5 للكائن.
crc32c سلسلة تجزئة crc32c للكائن.
etag سلسلة etag المرتبطة بهذا الكائن.
contentDisposition سلسلة ترتيب المحتوى المرتبط بهذا الكائن.
contentEncoding سلسلة ترميز المحتوى المرتبط بهذا الكائن.
contentLanguage سلسلة لغة المحتوى المرتبطة بهذا الكائن.
contentType سلسلة نوع المحتوى المرتبط بهذا الكائن.
metadata الخريطة <سلسلة ، سلسلة> أزواج مفتاح / قيمة لبيانات وصفية مخصصة إضافية يحددها المطور.

يحتوي request.resource على كل هذه العناصر باستثناء generation والتكوين etag metageneration تم timeCreated updated .

تحقق من صحة البيانات

يمكن أيضًا استخدام قواعد أمان Firebase للتخزين السحابي للتحقق من صحة البيانات ، بما في ذلك التحقق من صحة اسم الملف والمسار بالإضافة إلى خصائص البيانات الوصفية للملف مثل 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 أصبحت أكثر تعقيدًا ، فقد ترغب في التفاف مجموعات من الشروط في وظائف يمكنك إعادة استخدامها عبر مجموعة القواعد الخاصة بك. قواعد الأمان تدعم الوظائف المخصصة. يشبه بناء جملة الوظائف المخصصة JavaScript إلى حد ما ، ولكن وظائف قواعد أمان Firebase مكتوبة بلغة خاصة بالمجال لها بعض القيود المهمة:

  • يمكن أن تحتوي الوظائف على بيان return واحد فقط. لا يمكن أن تحتوي على أي منطق إضافي. على سبيل المثال ، لا يمكنهم تنفيذ حلقات أو استدعاء خدمات خارجية.
  • يمكن للوظائف الوصول تلقائيًا إلى الوظائف والمتغيرات من النطاق الذي يتم تحديدها فيه. على سبيل المثال ، الوظيفة المحددة في نطاق service firebase.storage لها حق الوصول إلى متغير resource ، وبالنسبة إلى Cloud Firestore فقط ، فإن الوظائف المضمنة مثل get() و exists() .
  • قد تستدعي الوظائف وظائف أخرى ولكنها قد لا تتكرر. إجمالي عمق مكدس الاستدعاء محدد بـ 10.
  • في قواعد الإصدار rules2 ، يمكن للوظائف تحديد المتغيرات باستخدام الكلمة الرئيسية let . يمكن أن تحتوي الدوال على أي عدد من ارتباطات let ، ولكن يجب أن تنتهي ببيان إرجاع.

يتم تعريف 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 إلى جعلها أكثر قابلية للصيانة مع تزايد تعقيد قواعدك.

الخطوات التالية

بعد هذه المناقشة حول الشروط ، يكون لديك فهم أكثر تعقيدًا للقواعد وأنت على استعداد للقيام بما يلي:

تعرف على كيفية التعامل مع حالات الاستخدام الأساسية ، وتعلم سير العمل لتطوير واختبار ونشر القواعد: