مدیریت و استقرار «قوانین امنیتی Firebase»

Firebase چندین ابزار برای مدیریت Security Rules دراختیارتان قرار می‌دهد که هرکدام در موارد خاصی مفید هستند و هرکدام از همان API مدیریت «قوانین امنیتی» Firebase در پس‌رانه استفاده می‌کنند.

مهم نیست از کدام ابزار برای فراخوانی آن استفاده می‌شود، Management API:

  • منبع قوانین را دریافت می‌کند: مجموعه‌ای از قوانین، معمولاً یک فایل کد حاوی عبارت‌های Firebase Security Rules.
  • فروشگاه‌ها منبع را به‌عنوان مجموعه قوانین تغییرناپذیر دریافت کردند.
  • استقرار هر مجموعه قانون را در یک نسخه ردیابی می‌کند. سرویس‌های فعال‌شده با Firebase Security Rules نسخه پخش را برای پروژه جستجو می‌کنند تا هر درخواست را برای منبع ایمن ارزیابی کنند.
  • قابلیت اجرای آزمایش‌های نحوی و معنایی مجموعه قوانین را فراهم می‌کند.

استفاده از Firebase CLI

با Firebase CLI، می‌توانید منابع محلی را بارگذاری کنید و نسخه‌های پخش را مستقر کنید. Firebase Local Emulator Suite CLI به شما امکان می‌دهد آزمایش محلی کامل منابع را انجام دهید.

استفاده از CLI به شما امکان می‌دهد قوانین خود را تحت کنترل نسخه با کد برنامه خود نگه دارید و قوانین را به‌عنوان بخشی از فرایند استقرار موجود خود مستقر کنید.

تولید فایل پیکربندی

وقتی پروژه Firebase خود را بااستفاده از Firebase CLI پیکربندی می‌کنید، یک فایل پیکربندی .rules در دایرکتوری پروژه خود ایجاد می‌کنید. از فرمان زیر برای شروع پیکربندی پروژه Firebase خود استفاده کنید:

Cloud Firestore

// Set up Firestore in your project directory, creates a .rules file
firebase init firestore

Realtime Database

// Set up Realtime Database in your project directory, creates a .rules file
firebase init database

Cloud Storage

// Set up Storage in your project directory, creates a .rules file
firebase init storage

ویرایش و به‌روزرسانی قوانین

منبع قوانینتان را مستقیماً در فایل پیکربندی .rules ویرایش کنید.

مطمئن شوید که هر ویرایشی که در Firebase CLI انجام می‌دهید در کنسول Firebase منعکس شود، یا اینکه به‌طور مداوم بااستفاده از کنسول Firebase یا Firebase CLI به‌روزرسانی‌ها را انجام دهید. درغیراین‌صورت، ممکن است به‌روزرسانی‌های انجام‌شده در کنسول Firebase را رونویسی کنید.

به‌روزرسانی‌هایتان را آزمایش کنید

Local Emulator Suite شبیه‌سازهایی برای همه محصولات فعال‌شده با «قوانین امنیتی» ارائه می‌دهد. موتور «قوانین امنیتی» برای هر شبیه‌ساز، ارزیابی نحوی و معنایی قوانین را انجام می‌دهد، بنابراین از آزمایش نحوی که API مدیریت «قوانین امنیتی» ارائه می‌دهد فراتر می‌رود.

اگر با CLI کار می‌کنید، Suite ابزاری عالی برای آزمایش Firebase Security Rules است. از Local Emulator Suite برای آزمایش به‌روزرسانی‌هایتان به‌صورت محلی استفاده کنید و مطمئن شوید که Security Rules برنامه‌تان رفتار موردنظرتان را نشان می‌دهد.

به‌روزرسانی‌هایتان را مستقر کنید

پس‌از به‌روزرسانی و آزمایش Security Rules، منابع را در تولید مستقر کنید.

برای Cloud Firestore Security Rules، فایل‌های .rules را با پایگاه‌های داده پیش‌فرض و نام‌گذاری‌شده اضافی مرتبط کنید. برای این کار، فایل firebase.json را مرور و به‌روز کنید.

از فرمان‌های زیر برای استقرار انتخابی Security Rules به‌تنهایی یا استقرار آن‌ها به‌عنوان بخشی از فرایند استقرار عادی‌تان استفاده کنید.

Cloud Firestore

// Deploy rules for all databases configured in your firebase.json
firebase deploy --only firestore:rules
// Deploy rules for the specified database configured in your firebase.json firebase deploy --only firestore:<databaseId>

Realtime Database

// Deploy your .rules file
firebase deploy --only database

Cloud Storage

// Deploy your .rules file
firebase deploy --only storage

استفاده از کنسول Firebase

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

ویرایش و به‌روزرسانی قوانین

  1. کنسول Firebase را باز کنید و پروژه‌تان را انتخاب کنید.
  2. سپس، Realtime Database، Cloud Firestore، یا فضای ذخیره‌سازی را از پیمایش محصول انتخاب کنید، سپس روی قوانین کلیک کنید تا به ویرایشگر Security Rules بروید.
  3. قوانینتان را مستقیماً در ویرایشگر ویرایش کنید.

به‌روزرسانی‌هایتان را آزمایش کنید

علاوه‌بر آزمایش نحو در میانای کاربری ویرایشگر، می‌توانید رفتار Security Rules معنایی را بااستفاده از منابع پایگاه داده و فضای ذخیره‌سازی پروژه‌تان مستقیماً در کنسول Firebase بااستفاده از Security RulesPlayground آزمایش کنید. صفحه زمین بازی قوانین را در ویرایشگر Security Rules باز کنید، تنظیمات را تغییر دهید و روی اجرا کلیک کنید. پیام تأیید را در بالای ویرایشگر پیدا کنید.

به‌روزرسانی‌هایتان را مستقر کنید

وقتی مطمئن شدید که به‌روزرسانی‌هایتان همان چیزی است که انتظار دارید، روی منتشر کردن کلیک کنید.

استفاده از Admin SDK

می‌توانید از Admin SDK برای Node.js مجموعه قوانین استفاده کنید. با این دسترسی برنامه‌ای، می‌توانید:

  • ابزارها، اسکریپت‌ها، داشبوردها، و خطوط لوله CI/CD سفارشی را برای مدیریت قوانین پیاده‌سازی کنید.
  • قوانین را در چندین پروژه Firebase راحت‌تر مدیریت کنید.

هنگام به‌روزرسانی قوانین به‌صورت برنامه‌نویسی، بسیار مهم است که از ایجاد تغییرات ناخواسته در کنترل دسترسی برنامه خود اجتناب کنید. Admin SDK کد خود را با در نظر گرفتن امنیت در درجه اول بنویسید، به‌ویژه هنگام به‌روزرسانی یا استقرار قوانین.

نکته مهم دیگری که باید به‌خاطر داشته باشید این است که انتشار Firebase Security Rules چند دقیقه طول می‌کشد تا کاملاً منتشر شود. هنگام استفاده از Admin SDK برای استقرار قوانین، حتماً از شرایط رقابتی که در آن برنامه شما فوراً به قوانینی متکی است که استقرار آن‌ها هنوز کامل نشده است، اجتناب کنید. اگر مورد استفاده شما به به‌روزرسانی‌های مکرر برای قوانین کنترل دسترسی نیاز دارد، راه‌حل‌هایی را درنظر بگیرید که از Cloud Firestore استفاده می‌کنند، که برای کاهش شرایط رقابتی با وجود به‌روزرسانی‌های مکرر طراحی شده است.

همچنین به این محدودیت‌ها توجه کنید:

  • قوانین باید کوچک‌تر از ۲۵۶ کیبی‌بایت نوشتار کدبندی‌شده UTF-8 هنگام سریال‌سازی باشند.
  • هر پروژه می‌تواند حداکثر ۲۵۰۰ مجموعه قانون مستقرشده داشته باشد. وقتی به این حد رسیدید، باید برخی‌از مجموعه‌قوانین قدیمی را حذف کنید تا بتوانید مجموعه‌قوانین جدید ایجاد کنید.

ایجاد و استقرار مجموعه قوانین Cloud Storage یا Cloud Firestore

یک گردش کار معمول برای مدیریت قوانین امنیتی با Admin SDK می‌تواند شامل سه مرحله مجزا باشد:

  1. ایجاد منبع فایل قوانین (اختیاری)
  2. ایجاد مجموعه قوانین
  3. انتشار یا پیاده‌سازی مجموعه قوانین جدید

کیت توسعه نرم‌افزار روشی برای ترکیب این مراحل در یک فراخوانی API برای قوانین امنیتی Cloud Storage و Cloud Firestore ارائه می‌دهد. برای مثال:

    const source = `service cloud.firestore {
      match /databases/{database}/documents {
        match /carts/{cartID} {
          allow create: if request.auth != null && request.auth.uid == request.resource.data.ownerUID;
          allow read, update, delete: if request.auth != null && request.auth.uid == resource.data.ownerUID;
        }
      }
    }`;
    // Alternatively, load rules from a file
    // const fs = require('fs');
    // const source = fs.readFileSync('path/to/firestore.rules', 'utf8');

    await admin.securityRules().releaseFirestoreRulesetFromSource(source);

این الگو برای قوانین Cloud Storage با releaseFirestoreRulesetFromSource() نیز کار می‌کند.

یا می‌توانید فایل قوانین را به‌عنوان شیء درون‌حافظه‌ای ایجاد کنید، مجموعه قوانین را ایجاد کنید، و مجموعه قوانین را به‌طور جداگانه برای کنترل دقیق‌تر این رویدادها مستقر کنید. برای مثال:

    const rf = admin.securityRules().createRulesFileFromSource('firestore.rules', source);
    const rs = await admin.securityRules().createRuleset(rf);
    await admin.securityRules().releaseFirestoreRuleset(rs);

به‌روزرسانی مجموعه‌قوانین Realtime Database

برای به‌روزرسانی مجموعه قوانین Realtime Database با Admin SDK، از روش‌های getRules() و setRules() admin.database استفاده کنید. می‌توانید مجموعه‌قوانین را در قالب JSON یا به‌صورت رشته‌ای که شامل نظرات است بازیابی کنید.

برای به‌روزرسانی مجموعه قوانین:

    const source = `{
      "rules": {
        "scores": {
          ".indexOn": "score",
          "$uid": {
            ".read": "$uid == auth.uid",
            ".write": "$uid == auth.uid"
          }
        }
      }
    }`;
    await admin.database().setRules(source);

مدیریت مجموعه‌قوانین

برای کمک به مدیریت مجموعه‌های بزرگ قوانین، Admin SDK به شما امکان می‌دهد همه قوانین موجود را با admin.securityRules().listRulesetMetadata فهرست کنید. برای مثال:

    const allRulesets = [];
    let pageToken = null;
    while (true) {
      const result = await admin.securityRules().listRulesetMetadata(pageToken: pageToken);
      allRulesets.push(...result.rulesets);
      pageToken = result.nextPageToken;
      if (!pageToken) {
        break;
      }
    }

برای استقرارهای بسیار بزرگ که درطول زمان به حد ۲۵۰۰ مجموعه قانون می‌رسند، می‌توانید منطقی ایجاد کنید تا قدیمی‌ترین قوانین را در یک چرخه زمانی ثابت حذف کند. برای مثال، برای حذف همه مجموعه‌قوانین مستقرشده برای بیش‌از ۳۰ روز:

    const thirtyDays = new Date(Date.now() - THIRTY_DAYS_IN_MILLIS);
    const promises = [];
    allRulesets.forEach((rs) => {
      if (new Date(rs.createTime) < thirtyDays) {
        promises.push(admin.securityRules().deleteRuleset(rs.name));
      }
    });
    await Promise.all(promises);
    console.log(`Deleted ${promises.length} rulesets.`);

استفاده از REST API

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

همچنین به این محدودیت‌ها توجه کنید:

  • قوانین باید کوچک‌تر از ۲۵۶ کیبی‌بایت نوشتار کدبندی‌شده UTF-8 هنگام سریال‌سازی باشند.
  • هر پروژه می‌تواند حداکثر ۲۵۰۰ مجموعه قانون مستقرشده داشته باشد. وقتی به این حد رسیدید، باید برخی‌از مجموعه‌قوانین قدیمی را حذف کنید تا بتوانید مجموعه‌قوانین جدید ایجاد کنید.

ایجاد و استقرار مجموعه قوانین Cloud Firestore یا Cloud Storage با REST

نمونه‌های این بخش از Firestore Security Rules استفاده می‌کنند، هرچند برای Cloud Storage Security Rules نیز کاربرد دارند.

این نمونه‌ها همچنین از cURL برای برقراری تماس‌های میانای برنامه‌سازی کاربردی استفاده می‌کنند. مراحل راه‌اندازی و ارسال نشان‌های اصالت‌سنجی حذف شده است. می‌توانید بااستفاده از API Explorer که با اسناد مرجع ادغام شده است، این API را آزمایش کنید.

مراحل معمول برای ایجاد و استقرار مجموعه قوانین بااستفاده از API مدیریت عبارتند از:

  1. ایجاد منابع فایل قوانین
  2. ایجاد مجموعه قوانین
  3. مجموعه قوانین جدید را منتشر (پیاده‌سازی) کنید.

ایجاد منبع

فرض کنید درحال کار روی پروژه Firebase secure_commerce هستید و می‌خواهید Cloud Firestore Security Rules قفل‌شده را در پایگاه داده‌ای در پروژه‌تان به‌نام east_store مستقر کنید.

می‌توانید این قوانین را در فایل firestore.rules پیاده‌سازی کنید.

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

ایجاد مجموعه قوانین

اکنون، اثر انگشت کدبندی‌شده با base64 برای این فایل تولید کنید. سپس می‌توانید از منبع موجود در این فایل برای پر کردن بار داده موردنیاز برای ایجاد مجموعه قوانین با فراخوانی projects.rulesets.create REST استفاده کنید. در اینجا، از فرمان cat برای درج محتوای firestore.rules در بار داده REST استفاده کنید.

برای ردیابی، برای مرتبط کردن این با پایگاه داده east_store، attachment_point را روی east_store تنظیم کنید.

curl -X POST -d '{
  "source": {
    "files": [
      {
        "content": "' $(cat storage.rules) '",
        "name": "firestore.rules",
        "fingerprint": <sha fingerprint>
      },
    "attachment_point": "firestore.googleapis.com/databases/east_store"
    ]
  }
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets'

میانای برنامه‌سازی کاربردی پاسخ اعتبارسنجی و نام مجموعه قوانین را برمی‌گرداند، برای مثال projects/secure_commerce/rulesets/uuid123.

انتشار (استقرار) مجموعه قوانین

اگر مجموعه قوانین معتبر باشد، مرحله نهایی استقرار مجموعه قوانین جدید در یک نسخه نام‌گذاری‌شده است.

curl -X POST -d '{
  "name": "projects/secure_commerce/releases/cloud.firestore/east_store"  ,
  "rulesetName": "projects/secure_commerce/rulesets/uuid123"
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/releases'

توجه داشته باشید که انتشار Firebase Security Rules چند دقیقه طول می‌کشد تا به‌طور کامل توزیع شود. هنگام استفاده از REST API مدیریت برای استقرار، حتماً از شرایط رقابتی که در آن برنامه‌تان فوراً به قوانینی متکی است که استقرار آن‌ها هنوز کامل نشده است اجتناب کنید.

به‌روزرسانی مجموعه‌قوانین Realtime Database با REST

‫Realtime Database میانای REST خودش را برای مدیریت Security Rules ارائه می‌دهد. مدیریت Firebase Realtime Database Security Rules ازطریق REST را ببینید.

مدیریت مجموعه‌قوانین با REST

برای کمک به مدیریت استقرار قوانین بزرگ، علاوه‌بر روش REST برای ایجاد مجموعه‌قوانین و نسخه‌های پخش، API مدیریت روش‌هایی را برای موارد زیر ارائه می‌دهد:

  • فهرست کردن، دریافت کردن، و حذف کردن مجموعه قوانین
  • فهرست کردن، دریافت کردن، و حذف کردن قوانین نسخه‌های پخش

برای استقرارهای بسیار بزرگ که درطول زمان به حد ۲۵۰۰ مجموعه قانون می‌رسند، می‌توانید منطقی ایجاد کنید تا قدیمی‌ترین قوانین را در یک چرخه زمانی ثابت حذف کند. برای مثال، برای حذف همه مجموعه‌قوانین مستقرشده برای بیش‌از ۳۰ روز، می‌توانید روش projects.rulesets.list را فراخوانی کنید، فهرست JSON اشیاء Ruleset را در کلیدهای createTime آن‌ها تجزیه کنید، سپس project.rulesets.delete را در مجموعه‌قوانین مربوطه با ruleset_id فراخوانی کنید.

آزمایش به‌روزرسانی‌ها با REST

درنهایت، میانای برنامه‌سازی کاربردی مدیریت به شما امکان می‌دهد آزمایش‌های نحوی و معنایی را روی منابع Cloud Firestore و Cloud Storage در پروژه‌های تولیدتان اجرا کنید.

آزمایش با این مؤلفه از API شامل موارد زیر است:

  1. تعریف شیء JSON TestSuite برای نمایش مجموعه‌ای از اشیاء TestCase
  2. درحال ارسال TestSuite
  3. تجزیه TestResult شیء را برگرداند

بیایید شیء TestSuite را با یک TestCase در فایل testcase.json تعریف کنیم. در این مثال، ما منبع زبان Security Rules را به‌صورت درون‌خطی با بار داده REST، در کنار مجموعه آزمون برای اجرا روی آن قوانین، ارسال می‌کنیم. ما انتظار ارزیابی «قوانین» و درخواست مشتری را که مجموعه قوانین باید درمقابل آن آزمایش شود مشخص می‌کنیم. همچنین می‌توانید بااستفاده از مقدار «کامل» مشخص کنید که گزارش آزمایش چقدر کامل است تا نشان دهید نتایج برای همه عبارت‌های زبان Security Rules باید در گزارش گنجانده شود، ازجمله عبارت‌هایی که با درخواست مطابقت نداشتند.

 {
  "source":
  {
    "files":
    [
      {
        "name": "firestore.rules",
        "content": "service cloud.firestore {
          match /databases/{database}/documents {
            match /users/{userId}{
              allow read: if (request.auth.uid == userId);
            }
            function doc(subpath) {
              return get(/databases/$(database)/documents/$(subpath)).data;
            }
            function isAccountOwner(accountId) {
              return request.auth.uid == accountId 
                  || doc(/users/$(request.auth.uid)).accountId == accountId;
            }
            match /licenses/{accountId} {
              allow read: if isAccountOwner(accountId);
            }
          }
        }"
      }
    ]
  },
  "testSuite":
  {
    "testCases":
    [
      {
        "expectation": "ALLOW",
        "request": {
           "auth": {"uid": "123"},
           "path": "/databases/(default)/documents/licenses/abcd",
           "method": "get"},
        "functionMocks": [
            {
            "function": "get",
            "args": [{"exact_value": "/databases/(default)/documents/users/123"}],
            "result": {"value": {"data": {"accountId": "abcd"}}}
            }
          ]
      }
    ]
  }
}

سپس می‌توانیم این TestSuite را برای ارزیابی با روش projects.test ارسال کنیم.

curl -X POST -d '{
    ' $(cat testcase.json) '
}' 'https://firebaserules.googleapis.com/v1/projects/secure_commerce/rulesets/uuid123:test'

TestReport برگردانده‌شده (شامل وضعیت «موفقیت/شکست» آزمایش، فهرست‌های پیام‌های اشکال‌زدایی، فهرست‌های عبارت‌های «قوانین» بازدیدشده و گزارش‌های ارزیابی آن‌ها) با وضعیت «موفقیت» تأیید می‌کند که دسترسی به‌درستی مجاز است.

مدیریت اجازه‌ها برای Cloud Storage Security Rules بین‌سرویسی

اگر Cloud Storage Security Rules ایجاد کنید که از محتوای سند Cloud Firestore برای ارزیابی شرایط امنیتی استفاده می‌کند، در کنسول Firebase یا Firebase CLI از شما خواسته می‌شود اجازه‌های اتصال دو محصول را فعال کنید.

اگر تصمیم بگیرید این امنیت بین‌سرویسی را غیرفعال کنید:

  1. ابتدا، قبل‌از غیرفعال کردن این ویژگی، قوانینتان را ویرایش کنید و همه عبارت‌هایی را که از عملکردهای Security Rules برای دسترسی به Cloud Firestore استفاده می‌کنند بردارید. درغیراین‌صورت، پس‌از غیرفعال شدن این ویژگی، ارزیابی‌های Security Rules باعث ناموفق شدن درخواست‌های «فضای ذخیره‌سازی» شما خواهد شد.

  2. با دنبال کردن راهنمای Cloud برای لغو نقش‌ها، از صفحه IAM در «کنسول Google Cloud» برای حذف نقش «Firebase Rules Firestore Service Agent» استفاده کنید.

دفعه بعدی که «قوانین» میان‌سرویسی را از CLI Firebase یا کنسول Firebase ذخیره کنید، از شما خواسته می‌شود این ویژگی را دوباره فعال کنید.