يتكامل 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 != null && 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; }
المثال الكامل
في ما يلي حالات بسيطة للأنواع الأربعة الشائعة من قيود المصادقة في المثال أدناه:
service firebase.storage { match /b/{bucket}/o { match /images { // Anyone can view any image (no auth, publicly readable) match /{allImages=**} { allow read; } // Only authenticated users can write to "public" images match /public/{imageId} { allow write: if request.auth != null; } // Only an individual user can write to "their" images match /{userId}/{imageId} { allow write: if request.auth.uid == userId; } // Allow a "group" of users to read/write to shared images // An owner metadata property on the object contains the groupId for reads // A custom token has been minted with a groupId property for writes match /{groupId}/{imageId} { allow read: if resource.metadata.owner == request.auth.token.groupId; allow write: if request.auth.token.groupId == groupId; } } } }