قواعد الأمان ومصادقة Firebase

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 معرّف المستأجر المرتبط بالحساب، إذا كان متوفّرًا، مثل 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;
  }
}

يمكنك الوصول إلى المطالبات المخصّصة في 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;
  }
}

للاطّلاع على المزيد من الأمثلة حول الاستفادة من Rules في Authentication، راجِع قواعد الأمان الأساسية.