欢迎参加我们将于 2022 年 10 月 18 日举办的 Firebase 峰会(线上线下同时进行),了解 Firebase 如何帮助您加快应用开发速度、满怀信心地发布应用并在之后需要时轻松地扩大应用规模。立即报名

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

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

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

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

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

Cloud Firestore

// Deploy your .rules file
firebase deploy --only firestore:rules

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

// 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 را با استفاده از خود API مدیریت مدیریت و اجرا کنید. API مدیریت بیشترین انعطاف را به شما می دهد.

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

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

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

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

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

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

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

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

بیایید فرض کنیم که روی پروژه Firebase secure_commerce خود کار می‌کنید و می‌خواهید قوانین ذخیره‌سازی ابری قفل‌شده را اجرا کنید. می توانید این قوانین را در فایل storage.rules پیاده سازی کنید.

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if false;
    }
  }
}

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

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

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

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

مجموعه قوانین پایگاه داده بیدرنگ را با 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 تأیید می‌کند که دسترسی به درستی مجاز است.