قوانین امنیتی Firebase را مدیریت و اجرا کنید

فایربیس ابزارهای مختلفی برای مدیریت Rules شما فراهم می‌کند که هر کدام در موارد خاصی مفید هستند و هر کدام از API مدیریت قوانین امنیتی فایربیس در بک‌اند استفاده می‌کنند.

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

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

از رابط Firebase استفاده کنید

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

استفاده از رابط خط فرمان (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) کار می‌کنید، این مجموعه ابزاری عالی برای آزمایش Firebase Security Rules است. از Local Emulator Suite برای آزمایش به‌روزرسانی‌های خود به صورت محلی و تأیید اینکه Rules برنامه شما رفتار مورد نظر شما را نشان می‌دهند، استفاده کنید.

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

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

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

از دستورات زیر برای استقرار انتخابی 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

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

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

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

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

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

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

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

از 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. انتشار یا استقرار مجموعه قوانین جدید

SDK روشی را برای ترکیب این مراحل در یک فراخوانی 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 مدیریت و مستقر کنید. API مدیریت، بیشترین انعطاف‌پذیری را به شما می‌دهد.

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

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

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

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

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

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

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

ایجاد یک منبع

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

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

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

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

حالا، یک اثر انگشت کدگذاری شده با base64 برای این فایل ایجاد کنید. سپس می‌توانید از منبع موجود در این فایل برای پر کردن payload مورد نیاز برای ایجاد یک مجموعه قوانین با فراخوانی projects.rulesets.create REST استفاده کنید. در اینجا، از دستور cat برای وارد کردن محتویات firestore.rules در payload 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'

این API یک پاسخ اعتبارسنجی و یک نام مجموعه قوانین، برای مثال 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 چند دقیقه طول می‌کشد. هنگام استفاده از Management REST API برای استقرار، مطمئن شوید که از شرایط رقابتی که در آن برنامه شما بلافاصله به قوانینی که استقرار آنها هنوز کامل نشده است، متکی می‌شود، جلوگیری می‌کنید.

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

Realtime Database رابط REST مخصوص به خود را برای مدیریت Rules ارائه می‌دهد. به بخش مدیریت Rules Realtime Database Firebase از طریق REST مراجعه کنید.

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

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

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

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

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

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

تست با این جزء از API شامل موارد زیر است:

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

بیایید یک شیء TestSuite با یک TestCase واحد در یک فایل testcase.json تعریف کنیم. در این مثال، منبع زبان Rules را به صورت درون‌خطی با بار داده REST، در کنار مجموعه تست برای اجرا روی آن قوانین، ارسال می‌کنیم. ما یک انتظار ارزیابی Rules و درخواست کلاینت را که قرار است مجموعه قوانین بر اساس آن آزمایش شوند، مشخص می‌کنیم. همچنین می‌توانید با استفاده از مقدار "FULL" برای نشان دادن نتایج مربوط به تمام عبارات زبان 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. ابتدا، قبل از غیرفعال کردن این ویژگی، قوانین خود را ویرایش کنید و تمام عباراتی را که از توابع Rules برای دسترسی به Cloud Firestore استفاده می‌کنند، حذف کنید. در غیر این صورت، پس از غیرفعال کردن این ویژگی، ارزیابی‌های Rules باعث می‌شود درخواست‌های Storage شما با شکست مواجه شوند.

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

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