Catch up on highlights from Firebase at Google I/O 2023. Learn more

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

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

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

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

المصادقة

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

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

يحتوي كائن 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 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 Firestore هذه ، ستتم مطالبتك في وحدة تحكم Firebase أو Firebase CLI لتمكين الأذونات لتوصيل المنتجين.

يمكنك تعطيل الميزة عن طريق إزالة دور IAM ، كما هو موضح في إدارة ونشر قواعد أمان Firebase .

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

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

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

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

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