قواعد الأمان الأساسية

Firebase Security Rules تتيح لك التحكّم في الوصول إلى بياناتك المخزّنة. يعني تركيب القواعد المرنة أنّه يمكنك إنشاء قواعد تطابق أي شيء، بدءًا من جميع عمليات الكتابة إلى قاعدة البيانات بأكملها وصولاً إلى العمليات على مستند معيّن.

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

للوصول إلى قواعدك وتعديلها، اتّبِع الخطوات الموضّحة في مقالة إدارة Firebase Security Rules ونشره.

القواعد التلقائية: وضع القفل

عند إنشاء قاعدة بيانات أو مثيل تخزين في وحدة تحكّم Firebase، يمكنك اختيار ما إذا كنت تريد أن Firebase Security Rules تقيّد الوصول إلى بياناتك (الوضع المقفل) أو تسمح لأي شخص بالوصول إليها (وضع الاختبار). في Cloud Firestore وRealtime Database، تمنع القواعد التلقائية للوضع المقفل جميع المستخدمين من الوصول إلى التطبيق. في Cloud Storage، يمكن للمستخدمين الذين تمّت مصادقتهم فقط الوصول إلى حِزم التخزين.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
  }
}

Realtime Database

{
  "rules": {
    ".read": false,
    ".write": false
  }
}

Cloud Storage

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if false;
    }
  }
}

قواعد بيئة التطوير

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

تذكَّر أنّ Firebase يتيح للعملاء الوصول المباشر إلى بياناتك، وأنّ Firebase Security Rules هي وسيلة الحماية الوحيدة التي تمنع المستخدمين الضارين من الوصول إلى بياناتك. يوفّر تحديد القواعد بشكل منفصل عن منطق المنتج عددًا من المزايا، منها أنّ العملاء ليسوا مسؤولين عن فرض الأمان، ولن تؤدي عمليات التنفيذ التي تتضمّن أخطاء إلى تعريض بياناتك للخطر، والأهم من ذلك أنّك لن تعتمد على خادم وسيط لحماية البيانات من العالم.

جميع المستخدمين الذين تمّت مصادقتهم

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

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    match /some_collection/{document} {
      allow read, write: if request.auth != null;
    }
  }
}

Realtime Database

{
  "rules": {
    "some_path": {
      ".read": "auth.uid !== null",
      ".write": "auth.uid !== null"
    }
  }
}

Cloud Storage

service firebase.storage {
  match /b/{bucket}/o {
    match /some_folder/{fileName} {
      allow read, write: if request.auth != null;
    }
  }
}

قواعد جاهزة للاستخدام

أثناء استعدادك لنشر تطبيقك، احرص على حماية بياناتك ومنح المستخدمين إذن الوصول إليها بشكل صحيح. استخدِم Authentication لإعداد أذونات الوصول المستندة إلى المستخدمين والقراءة مباشرةً من قاعدة البيانات لإعداد أذونات الوصول المستندة إلى البيانات.

ننصحك بكتابة القواعد أثناء تنظيم بياناتك، لأنّ طريقة إعداد القواعد تؤثّر في كيفية تقييد الوصول إلى البيانات في مسارات مختلفة.

إذن الوصول متاح لمالك المحتوى فقط

تمنع هذه القواعد الوصول إلى المحتوى إلا لمالكه الذي تم إثبات هويته. يمكن لمستخدم واحد فقط قراءة البيانات وكتابتها، ويتضمّن مسار البيانات معرّف المستخدم.

الحالات التي تعمل فيها هذه القاعدة: تعمل هذه القاعدة بشكل جيد إذا كانت البيانات مقسّمة حسب المستخدم، أي إذا كان المستخدم الوحيد الذي يحتاج إلى الوصول إلى البيانات هو المستخدم نفسه الذي أنشأ البيانات.

الحالات التي لا تعمل فيها هذه القاعدة: لا تعمل مجموعة القواعد هذه عندما يحتاج عدة مستخدمين إلى كتابة البيانات نفسها أو قراءتها، لأنّ المستخدمين سيستبدلون البيانات أو يتعذّر عليهم الوصول إلى البيانات التي أنشأوها.

لإعداد هذه القاعدة: أنشئ قاعدة تؤكّد أنّ المستخدم الذي يطلب الإذن بقراءة البيانات أو كتابتها هو المستخدم الذي يملك هذه البيانات.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow only authenticated content owners access
    match /some_collection/{userId}/{document} {
      allow read, write: if request.auth != null && request.auth.uid == userId
    }
  }
}

Realtime Database

{
  "rules": {
    "some_path": {
      "$uid": {
        // Allow only authenticated content owners access to their data
        ".read": "auth !== null && auth.uid === $uid",
        ".write": "auth !== null && auth.uid === $uid"
      }
    }
  }
}

Cloud Storage

// Grants a user access to a node matching their user ID
service firebase.storage {
  match /b/{bucket}/o {
    // Files look like: "user/<UID>/file.txt"
    match /user/{userId}/{fileName} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
  }
}

أذونات وصول مختلطة بين العامة والخاصة

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

حالات عمل هذه القاعدة: تعمل هذه القاعدة بشكل جيد مع التطبيقات التي تتطلّب عناصر قابلة للقراءة بشكل علني، ولكنها تحتاج إلى حصر إذن التعديل على مالكي هذه العناصر. على سبيل المثال، تطبيق دردشة أو مدوّنة.

الحالات التي لا تعمل فيها هذه القاعدة: كما هو الحال مع قاعدة "مالك المحتوى فقط"، لا تعمل مجموعة القواعد هذه عندما يحتاج عدة مستخدمين إلى تعديل البيانات نفسها. سيؤدي ذلك إلى أن يحلّ المستخدمون محل بعضهم البعض في البيانات.

لإعداد هذه القاعدة: أنشئ قاعدة تتيح إذن القراءة لجميع المستخدمين (أو جميع المستخدمين الذين تمّت مصادقتهم)، وتؤكّد أنّ المستخدم الذي يكتب البيانات هو المالك.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow public read access, but only content owners can write
    match /some_collection/{document} {
      // Allow public reads
      allow read: if true
      // Allow creation if the current user owns the new document
      allow create: if request.auth.uid == request.resource.data.author_uid;
      // Allow updates by the owner, and prevent change of ownership
      allow update: if request.auth.uid == request.resource.data.author_uid
                    && request.auth.uid == resource.data.author_uid;
      // Allow deletion if the current user owns the existing document
      allow delete: if request.auth.uid == resource.data.author_uid;
    }
  }
}

Realtime Database

{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data

  "rules": {
    "some_path": {
      "$uid": {
        ".read": true,
        // or ".read": "auth.uid !== null" for only authenticated users
        ".write": "auth.uid === $uid"
      }
    }
  }
}

Cloud Storage

service firebase.storage {
  match /b/{bucket}/o {
    // Files look like: "user/<UID>/file.txt"
    match /user/{userId}/{fileName} {
      allow read;
      allow write: if request.auth.uid == userId;
    }
  }
}

الوصول المستند إلى السمات والدور

لكي تعمل هذه القاعدة، يجب تحديد سمات وتعيينها للمستخدمين في بياناتك. Firebase Security Rules التحقّق من الطلب مقارنةً بالبيانات من قاعدة البيانات أو البيانات الوصفية للملف لتأكيد إمكانية الوصول أو رفضها

الحالات التي تعمل فيها هذه القاعدة: إذا كنت بصدد تعيين دور للمستخدمين، تتيح لك هذه القاعدة حصر الوصول استنادًا إلى الأدوار أو مجموعات معيّنة من المستخدمين. على سبيل المثال، إذا كنت تخزّن الدرجات، يمكنك منح مستويات وصول مختلفة لمجموعة "الطلاب" (قراءة المحتوى فقط)، ومجموعة "المعلّمين" (قراءة المحتوى والكتابة فيه في موادهم)، ومجموعة "مدراء المدارس" (قراءة كل المحتوى).

الحالات التي لا تعمل فيها هذه القاعدة: في Realtime Database وCloud Storage، لا يمكن أن تستخدم قواعدك طريقة get() التي يمكن أن تتضمّنها قواعد Cloud Firestore. وبالتالي، عليك تنظيم قاعدة البيانات أو البيانات الوصفية للملف بما يعكس السمات التي تستخدمها في قواعدك.

لإعداد هذه القاعدة: في Cloud Firestore، أدرِج حقلًا في مستندات المستخدمين يمكنك قراءته، ثم نظِّم القاعدة لقراءة هذا الحقل ومنح الإذن بالوصول بشكل مشروط. في Realtime Database، أنشئ مسار بيانات يحدّد مستخدمي تطبيقك ويمنحهم دورًا في عقدة فرعية.

يمكنك أيضًا إعداد مطالبات مخصّصة في Authentication ثم استرداد هذه المعلومات من المتغيّر auth.token في أي Firebase Security Rules.

السمات والأدوار المحدّدة بالبيانات

لا تعمل هذه القواعد إلا في Cloud Firestore وRealtime Database.

Cloud Firestore

تذكَّر أنّه في أي وقت تتضمّن فيه قواعدك عملية قراءة، مثل القواعد أدناه، سيتم تحصيل رسوم منك مقابل عملية القراءة في Cloud Firestore.

service cloud.firestore {
  match /databases/{database}/documents {
    // For attribute-based access control, Check a boolean `admin` attribute
    allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
    allow read: true;

    // Alterntatively, for role-based access, assign specific roles to users
    match /some_collection/{document} {
     allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Reader"
     allow write: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.role == "Writer"
   }
  }
}

Realtime Database

{
  "rules": {
    "some_path": {
      "${subpath}": {
        //
        ".write": "root.child('users').child(auth.uid).child('role').val() === 'admin'",
        ".read": true
      }
    }
  }
}

السمات والأدوار المخصّصة للمطالبات

لتنفيذ هذه القواعد، عليك إعداد مطالبات مخصّصة في Firebase Authentication، ثم استخدام المطالبات في قواعدك.

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // For attribute-based access control, check for an administrator 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": {
      "$uid": {
        // Create a custom claim for each role or group
        // you want to use
        ".write": "auth.uid !== null && auth.token.writer === true",
        ".read": "auth.uid !== null && auth.token.reader === true"
      }
    }
  }
}

Cloud Storage

service firebase.storage {
  // 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;
  }
}

سمات المستأجر

لتنفيذ هذه القواعد، عليك إعداد الاستخدام المتعدّد للمستأجرين في Google Cloud Identity Platform (GCIP)، ثم استخدام المستأجر في قواعدك. تسمح الأمثلة التالية بعمليات الكتابة من مستخدم في مستأجر معيّن، مثل tenant2-m6tyz

Cloud Firestore

service cloud.firestore {
  match /databases/{database}/documents {
    // For tenant-based access control, check for a tenantID
    allow write: if request.auth.token.firebase.tenant == 'tenant2-m6tyz';
    allow read: true;
  }
}

Realtime Database

{
  "rules": {
    "some_path": {
      "$uid": {
        // Only allow reads and writes if user belongs to a specific tenant
        ".write": "auth.uid !== null && auth.token.firebase.tenant === 'tenant2-m6tyz'",
        ".read": "auth.uid !== null
      }
    }
  }
}

Cloud Storage

service firebase.storage {
  // Only allow reads and writes if user belongs to a specific tenant
  match /files/{tenantId}/{fileName} {
    allow read: if request.auth != null;
    allow write: if request.auth.token.firebase.tenant == tenantId;
  }
}