قواعد الأمان ومصادقة 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"، يمكنك الاطّلاع على قواعد الأمان الأساسية