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

Firebase چندین ابزار را برای مدیریت Rules خود در اختیار شما قرار می دهد که هر کدام در موارد خاص مفید هستند و هر کدام از آنها با استفاده از یک API مدیریت قوانین امنیتی Firebase Security استفاده می کنند.

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

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

از 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 برای آزمایش به روز رسانی های خود به صورت محلی استفاده کنید و تأیید کنید که 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 کلیک کنید. به دنبال پیام تایید در بالای ویرایشگر بگردید.

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

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

از Admin SDK استفاده کنید

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

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

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

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

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

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

مجموعه قوانین 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;
      }
    }

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

    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 مدیریت بیشترین انعطاف را به شما می دهد.

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

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

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

مجموعه قوانین Realtime Database با REST به روز کنید

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

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

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

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

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

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

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

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

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

بیایید یک شی TestSuite با یک TestCase در یک فایل testcase.json تعریف کنیم. در این مثال، منبع زبان Rules را به صورت درون خطی با بار REST، در کنار مجموعه آزمایشی ارسال می کنیم تا روی آن قوانین اجرا شود. ما انتظارات ارزیابی قوانین و درخواست مشتری را مشخص می کنیم که مجموعه قوانین در برابر آن باید آزمایش شود. همچنین می‌توانید مشخص کنید که گزارش آزمون چقدر کامل است، با استفاده از مقدار "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 برگشتی (شامل وضعیت SUCCESS/FAILURE آزمایش، لیست پیام‌های اشکال‌زدایی، فهرست عبارات قوانین بازدید شده و گزارش‌های ارزیابی آنها) با وضعیت SUCCESS تأیید می‌کند که دسترسی به درستی مجاز است.

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

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

اگر تصمیم به غیرفعال کردن چنین امنیت خدمات متقابل دارید:

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

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

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