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

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

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

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

از Firebase CLI استفاده کنید

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

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

یک فایل پیکربندی ایجاد کنید

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

Cloud Firestore

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

پایگاه داده بیدرنگ

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

فضای ذخیره ابری

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

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

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

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

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

پایگاه داده بیدرنگ

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

فضای ذخیره ابری

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

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

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

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

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

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

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

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

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

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

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

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

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

نکته مهم دیگری که باید در نظر داشت این است که انتشار کامل قوانین Firebase چند دقیقه طول می کشد. هنگام استفاده از 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);

مجموعه قوانین پایگاه داده بیدرنگ را به روز کنید

برای به روز رسانی قوانین پایگاه داده بیدرنگ با 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 برای چندین پایگاه داده Cloud Firestore در پروژه شما مناسب هستند، اما ممکن است بخواهید قوانین امنیتی Firebase را با استفاده از خود API مدیریت مدیریت و اجرا کنید. API مدیریت بیشترین انعطاف را به شما می دهد.

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

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

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

مثال‌های موجود در این بخش از قوانین Firestore استفاده می‌کنند، اگرچه در مورد قوانین ذخیره‌سازی ابری نیز اعمال می‌شوند.

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

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

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

یک منبع ایجاد کنید

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

مجموعه قوانین پایگاه داده بیدرنگ را با REST به روز کنید

پایگاه داده Realtime رابط REST خود را برای مدیریت قوانین ارائه می دهد. به مدیریت قوانین پایگاه داده بیدرنگ 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" برای نشان دادن نتایج برای همه عبارات زبان قوانین باید در گزارش گنجانده شود، از جمله عباراتی که با درخواست مطابقت ندارند.

 {
  "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 بین سرویس‌ها مدیریت کنید

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

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

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

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

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