Firebase Security Rules توفّر إمكانية التحكّم في الوصول والتحقّق من صحة البيانات بتنسيق يتيح مستويات متعددة من التعقيد. لإنشاء أنظمة وصول مستندة إلى المستخدمين والأدوار تحافظ على أمان بيانات المستخدمين، يمكنك استخدام Firebase Authentication مع Firebase Security Rules.
تحديد هوية المستخدمين
يحدّد Authentication المستخدمين الذين يطلبون الوصول إلى بياناتك ويوفّر هذه المعلومات كمتغيّر يمكنك الاستفادة منه في قواعدك. يحتوي المتغيّر auth على المعلومات التالية:
-
uid: رقم تعريف المستخدم الفريد، الذي يتم تعيينه للمستخدم الذي يقدّم الطلب. token: خريطة للقيم التي تم جمعها من خلال Authentication.
يحتوي المتغيّر auth.token على القيم التالية:
| الحقل | الوصف |
|---|---|
email |
عنوان البريد الإلكتروني المرتبط بالحساب، إن توفّر |
email_verified |
true إذا أثبت المستخدم أنّه يملك إذن الوصول إلى عنوان البريد الإلكتروني email يتحقّق بعض مقدّمي الخدمات تلقائيًا من عناوين البريد الإلكتروني التي يملكونها. |
phone_number |
رقم الهاتف المرتبط بالحساب، إن توفّر |
name |
الاسم المعروض للمستخدم، في حال ضبطه |
sub |
معرّف المستخدم في Firebase ويكون هذا المعرّف فريدًا ضمن المشروع. |
firebase.identities |
قاموس لجميع الهويات المرتبطة بحساب هذا المستخدم يمكن أن تكون مفاتيح القاموس أيًا مما يلي: email أو phone أو google.com أو facebook.com أو github.com أو twitter.com. قيم القاموس هي مصفوفات من المعرّفات الفريدة لكل موفّر هوية مرتبط بالحساب. على سبيل المثال، يحتوي auth.token.firebase.identities["google.com"][0] على رقم تعريف مستخدم Google الأول المرتبط بالحساب. |
firebase.sign_in_provider |
مقدّم خدمة تسجيل الدخول المستخدَم للحصول على هذا الرمز المميّز يمكن أن تكون إحدى السلاسل التالية: custom أو password أو phone أو anonymous أو google.com أو facebook.com أو github.com أو twitter.com. |
firebase.tenant |
tenantId المرتبط بالحساب، في حال توفّره، مثل tenant2-m6tyz |
إذا أردت إضافة سمات مصادقة مخصّصة، يحتوي المتغيّر auth.token أيضًا على أي مطالبات مخصّصة تحدّدها.
عندما لا يكون المستخدم الذي يطلب الوصول مسجِّلاً الدخول، يكون المتغيّر auth هو null.
يمكنك الاستفادة من ذلك في قواعدك إذا أردت، على سبيل المثال، تقييد إذن الوصول للقراءة
للمستخدمين الذين تمت مصادقتهم — auth != null. ومع ذلك، ننصح عمومًا
بتقييد إذن الكتابة بشكل أكبر.
لمزيد من المعلومات حول المتغيّر auth، يُرجى الاطّلاع على المستندات المرجعية لكل من
Cloud Firestore وRealtime Database وCloud Storage.
الاستفادة من معلومات المستخدم في القواعد
من الناحية العملية، فإن استخدام المعلومات المصادق عليها في القواعد يجعل القواعد أكثر قوة ومرونة. يمكنك التحكّم في الوصول إلى البيانات استنادًا إلى هوية المستخدم.
في قواعدك، حدِّد كيف تتطابق المعلومات في المتغيّر auth (معلومات المستخدم لمقدِّم الطلب) مع معلومات المستخدم المرتبطة بالبيانات المطلوبة.
على سبيل المثال، قد يحتاج تطبيقك إلى التأكّد من أنّ المستخدمين يمكنهم قراءة بياناتهم
وكتابتها فقط. في هذا السيناريو، ستحتاج إلى مطابقة بين المتغيّر auth.uid ورقم تعريف المستخدم في البيانات المطلوبة:
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// Make sure the uid of the requesting user matches name of the user
// document. The wildcard expression {userId} makes the userId variable
// available in rules.
match /users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
}
}
Realtime Database
{
"rules": {
"users": {
"$userId": {
// grants write access to the owner of this user account
// whose uid must exactly match the key ($userId)
".write": "$userId === auth.uid"
}
}
}
}
Cloud Storage
service firebase.storage {
// Only a user can upload their file, but anyone can view it
match /users/{userId}/{fileName} {
allow read;
allow write: if request.auth != null && request.auth.uid == userId;
}
}
تحديد معلومات المستخدم المخصّصة
يمكنك الاستفادة بشكل أكبر من المتغيّر auth لتحديد الحقول المخصّصة التي يتم تخصيصها
لمستخدمي تطبيقك.
على سبيل المثال، لنفترض أنّك تريد إنشاء دور "مشرف" يتيح إذن الكتابة في مسارات معيّنة. يمكنك تعيين هذه السمة للمستخدمين، ثم الاستفادة منها في القواعد التي تمنح الوصول إلى المسارات.
في Cloud Firestore، يمكنك إضافة حقل مخصّص إلى مستندات المستخدمين واسترداد قيمة هذا الحقل من خلال قراءة مضمّنة في قواعدك. لذلك، ستبدو القاعدة المستندة إلى المشرف مثل المثال التالي:
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents/some_collection: {
// Remember that, in Cloud Firestore, reads embedded in your rules are billed operations
write: if request.auth != null && get(/databases/(database)/documents/users/$(request.auth.uid)).data.admin == true;
read: if request.auth != null;
}
}
يمكنك الوصول إلى المطالبات المخصّصة في Security Rules بعد إنشاء المطالبات المخصّصة في Authentication. يمكنك بعد ذلك
الإشارة إلى هذه المطالبات المخصّصة باستخدام المتغيّر auth.token.
Cloud Firestore
service cloud.firestore {
match /databases/{database}/documents {
// For attribute-based access control, check for an admin claim
allow write: if request.auth.token.admin == true;
allow read: true;
// Alterntatively, for role-based access, assign specific roles to users
match /some_collection/{document} {
allow read: if request.auth.token.reader == "true";
allow write: if request.auth.token.writer == "true";
}
}
}
Realtime Database
{
"rules": {
"some_path": {
"$sub_path": {
// Create a custom claim for the admin role
".write": "auth.uid !== null && auth.token.writer === true",
".read": "auth.uid !== null"
}
}
}
}
Cloud Storage
service firebase.storage {
// Create a custom claim for the admin role
match /files/{fileName} {
allow read: if request.auth.uid != null;
allow write: if request.auth.token.admin == true;
}
}
للاطّلاع على المزيد من الأمثلة على Security Rules الأساسية التي تستفيد من Authentication، يُرجى الاطّلاع على قواعد الأمان الأساسية.