قوانین امنیتی و احراز هویت Firebase

Firebase Security Rules کنترل دسترسی و اعتبارسنجی داده‌ها را در قالبی ارائه می‌دهند که از سطوح مختلف پیچیدگی پشتیبانی می‌کند. برای ساخت سیستم‌های دسترسی مبتنی بر کاربر و مبتنی بر نقش که داده‌های کاربران شما را ایمن نگه می‌دارند، از Firebase Authentication به همراه Firebase Security Rules استفاده کنید.

شناسایی کاربران

Authentication کاربرانی را که درخواست دسترسی به داده‌های شما را دارند شناسایی می‌کند و آن اطلاعات را به عنوان متغیری که می‌توانید در قوانین خود از آن استفاده کنید، ارائه می‌دهد. متغیر auth شامل اطلاعات زیر است:

  • uid : یک شناسه کاربری منحصر به فرد که به کاربر درخواست کننده اختصاص داده می‌شود.
  • token : نقشه‌ای از مقادیر جمع‌آوری‌شده توسط Authentication .

متغیر auth.token شامل مقادیر زیر است:

میدان توضیحات
email آدرس ایمیل مرتبط با حساب، در صورت وجود.
email_verified اگر کاربر تأیید کرده باشد که به آدرس email دسترسی دارد، true برمی‌گرداند. برخی از ارائه‌دهندگان به‌طور خودکار آدرس‌های ایمیل متعلق به خود را تأیید می‌کنند.
phone_number شماره تلفن مرتبط با حساب، در صورت وجود.
name نام نمایشی کاربر، در صورت تنظیم.
sub شناسه کاربری فایربیس کاربر. این شناسه در یک پروژه منحصر به فرد است.
firebase.identities دیکشنری تمام هویت‌هایی که با حساب کاربری این کاربر مرتبط هستند. کلیدهای دیکشنری می‌توانند هر یک از موارد زیر باشند: email ، phone ، google.com ، facebook.com ، github.com ، twitter.com . مقادیر دیکشنری آرایه‌هایی از شناسه‌های منحصر به فرد برای هر ارائه‌دهنده هویت مرتبط با حساب هستند. به عنوان مثال، auth.token.firebase.identities["google.com"][0] شامل اولین شناسه کاربری گوگل مرتبط با حساب است.
firebase.sign_in_provider ارائه‌دهنده‌ی ورود به سیستم که برای دریافت این توکن استفاده شده است. می‌تواند یکی از رشته‌های زیر باشد: custom ، password ، phone ، anonymous ، google.com ، facebook.com ، github.com ، twitter.com .
firebase.tenant tenantId مرتبط با حساب، در صورت وجود. مانند tenant2-m6tyz

اگر می‌خواهید ویژگی‌های احراز هویت سفارشی‌شده‌ای اضافه کنید، متغیر auth.token شامل هرگونه claim سفارشی که مشخص می‌کنید نیز می‌شود.

وقتی کاربری که درخواست دسترسی می‌کند وارد سیستم نشده باشد، متغیر 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 برای تعریف فیلدهای سفارشی اختصاص داده شده به کاربران برنامه خود، بیشتر استفاده کنید.

برای مثال، فرض کنید می‌خواهید یک نقش "admin" ایجاد کنید که دسترسی نوشتن در مسیرهای خاص را فعال کند. شما این ویژگی را به کاربران اختصاص می‌دهید و سپس آن را در قوانین اعطای دسترسی در مسیرها اعمال می‌کنید.

در Cloud Firestore ، می‌توانید یک فیلد سفارشی به اسناد کاربران اضافه کنید و مقدار آن فیلد را با یک read تعبیه‌شده در قوانین خود بازیابی کنید. بنابراین، قانون مبتنی بر ادمین شما مانند مثال زیر خواهد بود:

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;
  }
}

شما می‌توانید پس از ایجاد ادعاهای سفارشی در Authentication در Rules به ادعاهای سفارشی دسترسی پیدا کنید. سپس می‌توانید با استفاده از متغیر 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 استفاده می‌کنند، به قوانین پایه‌ی امنیتی مراجعه کنید.