Firebase Security Rules توفّر إمكانية التحكّم في الوصول إلى البيانات والتحقّق من صحتها بتنسيق يتيح التعامل مع مستويات متعدّدة من التعقيد. لإنشاء أنظمة وصول مستندة إلى المستخدمين والأدوار تحافظ على أمان بيانات المستخدمين، استخدِم Firebase Authentication مع Firebase Security Rules.
تحديد هوية المستخدمين
تحدّد خدمة Authentication هوية المستخدمين الذين يطلبون الوصول إلى بياناتك وتوفّر هذه
المعلومات كمتغيّر يمكنك الاستفادة منه في قواعدك. يحتوي المتغيّر auth على المعلومات التالية:
uid: رقم تعريف مستخدم فريد يتم تعيينه للمستخدم الذي يطلب الوصول.token: خريطة للقيم التي تجمعها خدمة Authentication.
يحتوي المتغيّر auth.token على القيم التالية:
| الحقل | الوصف |
|---|---|
email |
عنوان البريد الإلكتروني المرتبط بالحساب، إذا كان متوفّرًا |
email_verified |
true إذا أكّد المستخدم أنّه يمكنه الوصول إلى عنوان email تؤكّد بعض الخدمات تلقائيًا عناوين البريد الإلكتروني التي تملكها. |
phone_number |
رقم الهاتف المرتبط بالحساب، إذا كان متوفّرًا |
name |
الاسم المعروض للمستخدم، إذا تم ضبطه |
sub |
رقم تعريف المستخدم (UID) في 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 |
رقم تعريف المستأجر المرتبط بالحساب، إذا كان متوفّرًا، مثلاً 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، يُرجى الاطّلاع على قواعد الأمان الأساسية.