قوانین امنیتی و اصالت‌سنجی 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 UID کاربر. این شناسه در پروژه یکتا است.
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 tenantId مرتبط با حساب، درصورت وجود. برای مثال 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;
  }
}

پس‌از ایجاد ادعاهای سفارشی در Authentication، می‌توانید به ادعاهای سفارشی در Security 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;
  }
}

برای دیدن نمونه‌های بیشتر از بهره‌برداری از Authentication Security Rules پایه، قوانین امنیتی پایه را ببینید.