আপনার Cloud Firestore নিরাপত্তা সংক্রান্ত নিয়ম পরীক্ষা করুন

আপনি অ্যাপ তৈরি করার সময়, আপনার Cloud Firestore ডেটাবেসে অ্যাক্সেস লক ডাউন করতে চাইতে পারেন। তবে, লঞ্চ করার আগে, আপনাকে আরও সূক্ষ্ম Cloud Firestore Security Rules করতে হবে। Cloud Firestore এমুলেটরের সাহায্যে, আপনার অ্যাপের সাধারণ ফিচার ও আচরণ প্রোটোটাইপ ও টেস্ট করার পাশাপাশি, আপনি ইউনিট টেস্ট লিখতে পারেন যা আপনার Cloud Firestore Security Rules-এর আচরণ চেক করে।

কুইকস্টার্ট

সহজ নিয়ম সহ কয়েকটি প্রাথমিক টেস্ট কেসের জন্য, কুইকস্টার্ট স্যাম্পেল ব্যবহার করে দেখুন।

Cloud Firestore Security Rules বুঝুন

আপনি মোবাইল এবং ওয়েব ক্লায়েন্ট লাইব্রেরি ব্যবহার করার সময় সার্ভারলেস যাচাইকরণ, অনুমোদন এবং ডেটা যাচাইকরণের জন্য Firebase Authentication এবং Cloud Firestore Security Rules প্রয়োগ করুন।

Cloud Firestore Security Rules-এ দুটি অংশ অন্তর্ভুক্ত:

  1. একটি match স্টেটমেন্ট যা আপনার ডেটাবেসে ডকুমেন্ট শনাক্ত করে।
  2. একটি allow এক্সপ্রেশন যা সেইসব ডকুমেন্টের অ্যাক্সেস কন্ট্রোল করে।

Firebase Authentication ব্যবহারকারীর ক্রেডেনশিয়াল যাচাই করে এবং ব্যবহারকারী-ভিত্তিক ও ভূমিকা-ভিত্তিক অ্যাক্সেস সিস্টেমের জন্য ভিত্তি প্রদান করে।

Rules মোবাইল/ওয়েব ক্লায়েন্ট লাইব্রেরি থেকে প্রতিটি ডেটাবেস অনুরোধ কোনও ডেটা পড়া বা লেখার আগে আপনার নিরাপত্তা সংক্রান্ত নিয়মের সাথে মিলিয়ে মূল্যায়ন করা হয়। নিয়ম অনুযায়ী নির্দিষ্ট করা কোনও ডকুমেন্ট পাথে অ্যাক্সেস না দেওয়া হলে, সম্পূর্ণ অনুরোধ বাতিল হয়ে যায়।

Cloud Firestore Security Rules ব্যবহার শুরু করুন থেকে Cloud Firestore Security Rules সম্পর্কে আরও জানুন।

এমুলেটর ইনস্টল করুন

Cloud Firestore এমুলেটর ইনস্টল করতে, Firebase CLI ব্যবহার করুন এবং নিচের কমান্ড রান করুন:

firebase setup:emulators:firestore

ইমুলেটর রান করুন

আপনার ওয়ার্কিং ডিরেক্টরিতে Firebase প্রোজেক্ট ইনিশিয়ালাইজ করার মাধ্যমে শুরু করুন। Firebase CLI ব্যবহার করার সময় এটি একটি সাধারণ প্রথম ধাপ।

firebase init

নিম্নলিখিত কমান্ড ব্যবহার করে এমুলেটর চালু করুন। আপনি প্রসেস বন্ধ না করা পর্যন্ত এমুলেটর চলতে থাকবে:

firebase emulators:start --only firestore

অনেক ক্ষেত্রে আপনি এমুলেটর চালু করতে, টেস্ট স্যুট চালাতে এবং তারপরে টেস্ট চালানোর পরে এমুলেটর বন্ধ করতে চান। emulators:exec কমান্ড ব্যবহার করে আপনি সহজেই এটি করতে পারবেন:

firebase emulators:exec --only firestore "./my-test-script.sh"

চালু করার সময় এমুলেটর ডিফল্ট পোর্টে (৮০৮০) রান করার চেষ্টা করবে। আপনি আপনার firebase.json ফাইলের "emulators" বিভাগটি পরিবর্তন করে এমুলেটর পোর্ট পরিবর্তন করতে পারেন:

{
  // ...
  "emulators": {
    "firestore": {
      "port": "YOUR_PORT"
    }
  }
}

এমুলেটর চালানোর আগে

এমুলেটর ব্যবহার করা শুরু করার আগে, নিম্নলিখিত বিষয়গুলি মনে রাখবেন:

  • এমুলেটর প্রথমে আপনার firebase.json ফাইলের firestore.rules ফিল্ডে নির্দিষ্ট করা নিয়ম লোড করবে। এটি আপনার Cloud Firestore Security Rules সহ লোকাল ফাইলের নাম আশা করে এবং সব প্রোজেক্টে সেইসব নিয়ম প্রয়োগ করে। আপনি যদি লোকাল ফাইল পাথ না দেন বা নিচে বর্ণিত loadFirestoreRules পদ্ধতি ব্যবহার না করেন, তাহলে এমুলেটর সব প্রজেক্টকে ওপেন রুল হিসেবে বিবেচনা করে।
  • বেশিরভাগ Firebase SDK সরাসরি এমুলেটরের সাথে কাজ করলেও, শুধুমাত্র @firebase/rules-unit-testing লাইব্রেরি নিরাপত্তা নিয়মে auth মক করা সাপোর্ট করে, যার ফলে ইউনিট টেস্ট অনেক সহজ হয়ে যায়। এছাড়াও, লাইব্রেরিটি কিছু এমুলেটর-নির্দিষ্ট ফিচার সমর্থন করে যেমন সমস্ত ডেটা মুছে ফেলা, নিচে তালিকাভুক্ত হিসাবে.
  • এছাড়াও, এমুলেটরগুলি ক্লায়েন্ট SDK-এর মাধ্যমে প্রদান করা প্রোডাকশন Firebase Auth টোকেন গ্রহণ করবে এবং সেই অনুযায়ী নিয়মগুলি মূল্যায়ন করবে, যা ইন্টিগ্রেশন এবং ম্যানুয়াল টেস্টে আপনার অ্যাপ্লিকেশনকে সরাসরি এমুলেটরগুলির সাথে কানেক্ট করার অনুমতি দেয়।

লোকাল ইউনিট টেস্ট রান করুন

v9 জাভাস্ক্রিপ্ট SDK-এর মাধ্যমে লোকাল ইউনিট টেস্ট রান করুন

Firebase তার ভার্সন 9 জাভাস্ক্রিপ্ট SDK এবং ভার্সন 8 SDK-এর সাথে নিরাপত্তা সংক্রান্ত নিয়মের ইউনিট টেস্টিং লাইব্রেরি ডিস্ট্রিবিউট করে। লাইব্রেরি API-গুলি উল্লেখযোগ্যভাবে আলাদা। আমরা v9 টেস্টিং লাইব্রেরি সাজেস্ট করি, যা আরও স্ট্রিমলাইন করা এবং ইমুলেটরের সাথে কানেক্ট করার জন্য কম সেট-আপের প্রয়োজন হয় এবং এইভাবে প্রোডাকশন রিসোর্সের আকস্মিক ব্যবহার নিরাপদে এড়ানো যায়। ব্যাকওয়ার্ড কম্প্যাটিবিলিটির জন্য, আমরা v8 টেস্টিং লাইব্রেরি উপলভ্য করা চালিয়ে যাব।

লোকালি রান করে এমন এমুলেটরের সাথে ইন্টার‍্যাক্ট করতে @firebase/rules-unit-testing মডিউল ব্যবহার করুন। আপনি টাইমআউট বা ECONNREFUSED সংক্রান্ত সমস্যা পেলে, এমুলেটরটি আসলেই চলছে কিনা তা ডবল-চেক করুন।

আমরা Node.js-এর সাম্প্রতিক ভার্সন ব্যবহার করার জন্য বিশেষভাবে সাজেস্ট করি যাতে আপনি async/await নোটেশন ব্যবহার করতে পারেন। আপনি যে আচরণ পরীক্ষা করতে চান তার প্রায় সবকটিতেই অ্যাসিঙ্ক্রোনাস ফাংশন থাকে এবং টেস্টিং মডিউলটি প্রমিস-ভিত্তিক কোডের সাথে কাজ করার জন্য ডিজাইন করা হয়েছে।

v9 Rules ইউনিট টেস্টিং লাইব্রেরি সবসময় এমুলেটর সম্পর্কে সচেতন থাকে এবং আপনার প্রোডাকশন রিসোর্স কখনও স্পর্শ করে না।

আপনি v9 মডিউলার ইমপোর্ট স্টেটমেন্ট ব্যবহার করে লাইব্রেরি ইমপোর্ট করেন। যেমন:

import {
  assertFails,
  assertSucceeds,
  initializeTestEnvironment
} from "@firebase/rules-unit-testing"

// Use `const { … } = require("@firebase/rules-unit-testing")` if imports are not supported
// Or we suggest `const testing = require("@firebase/rules-unit-testing")` if necessary.

ইমপোর্ট করা হয়ে গেলে, ইউনিট টেস্ট প্রয়োগ করার মধ্যে এগুলি অন্তর্ভুক্ত থাকে:

  • initializeTestEnvironment-এ কল করার মাধ্যমে RulesTestEnvironment তৈরি ও কনফিগার করা।
  • নিয়ম ট্রিগার না করে টেস্ট ডেটা সেট-আপ করা, একটি সুবিধাজনক পদ্ধতি ব্যবহার করে যা আপনাকে সাময়িকভাবে সেগুলি বাইপাস করতে দেয়, RulesTestEnvironment.withSecurityRulesDisabled.
  • টেস্ট ডেটা ও পরিবেশ ক্লিন-আপ করার জন্য কল সহ টেস্ট স্যুট ও প্রতি-টেস্ট আগে/পরে হুক সেট-আপ করা, যেমন RulesTestEnvironment.cleanup() বা RulesTestEnvironment.clearFirestore()।
  • RulesTestEnvironment.authenticatedContext এবং RulesTestEnvironment.unauthenticatedContext ব্যবহার করে যাচাইকরণের স্ট্যাটাস নকল করে এমন টেস্ট কেস প্রয়োগ করা।

সাধারণ পদ্ধতি ও ইউটিলিটি ফাংশন

এছাড়াও, v9 SDK-তে এমুলেটর-নির্দিষ্ট টেস্ট পদ্ধতি দেখুন।

initializeTestEnvironment() => RulesTestEnvironment

এই ফাংশনটি নিয়ম ইউনিট পরীক্ষার জন্য একটি টেস্ট এনভায়রনমেন্ট শুরু করে। টেস্ট সেট-আপের জন্য প্রথমে এই ফাংশনটি কল করুন। সঠিকভাবে এক্সিকিউট করার জন্য এমুলেটর চালু থাকতে হবে।

ফাংশনটি একটি ঐচ্ছিক অবজেক্ট গ্রহণ করে যা একটি TestEnvironmentConfig সংজ্ঞায়িত করে, যার মধ্যে একটি প্রোজেক্ট আইডি এবং এমুলেটর কনফিগারেশন সেটিংস থাকতে পারে।

let testEnv = await initializeTestEnvironment({
  projectId: "demo-project-1234",
  firestore: {
    rules: fs.readFileSync("firestore.rules", "utf8"),
  },
});

RulesTestEnvironment.authenticatedContext({ user_id: string, tokenOptions?: TokenOptions }) => RulesTestContext

এই পদ্ধতি একটি RulesTestContext তৈরি করে, যা যাচাই করা ব্যবহারকারীর মতো কাজ করে। ফেরত আসা কনটেক্সটের মাধ্যমে তৈরি করা অনুরোধে একটি মক যাচাইকরণ টোকেন অ্যাটাচ করা থাকবে। বিকল্প হিসেবে, কাস্টম দাবি বা Authentication টোকেন পেলোডের জন্য ওভাররাইড সংজ্ঞায়িত করে এমন একটি অবজেক্ট পাস করুন।

initializeTestEnvironment-এর মাধ্যমে কনফিগার করা ইনস্ট্যান্স সহ কনফিগার করা যেকোনও এমুলেটর ইনস্ট্যান্স অ্যাক্সেস করতে, আপনার টেস্টে রিটার্ন করা টেস্ট কনটেক্সট অবজেক্ট ব্যবহার করুন।

// Assuming a Firestore app and the Firestore emulator for this example
import { setDoc } from "firebase/firestore";

const alice = testEnv.authenticatedContext("alice", { … });
// Use the Firestore instance associated with this context
await assertSucceeds(setDoc(alice.firestore().doc('/users/alice'), { ... });

RulesTestEnvironment.unauthenticatedContext() => RulesTestContext

এই পদ্ধতিটি একটি RulesTestContext তৈরি করে, যা এমন একটি ক্লায়েন্টের মতো আচরণ করে যা যাচাইকরণের মাধ্যমে লগ-ইন করা হয় না। ফেরত আসা কনটেক্সটের মাধ্যমে তৈরি করা অনুরোধে Firebase Auth টোকেন অ্যাটাচ করা থাকবে না।

initializeTestEnvironment-এর মাধ্যমে কনফিগার করা ইনস্ট্যান্স সহ কনফিগার করা যেকোনও এমুলেটর ইনস্ট্যান্স অ্যাক্সেস করতে, আপনার টেস্টে রিটার্ন করা টেস্ট কনটেক্সট অবজেক্ট ব্যবহার করুন।

// Assuming a Cloud Storage app and the Storage emulator for this example
import { getStorage, ref, deleteObject } from "firebase/storage";

const alice = testEnv.unauthenticatedContext();

// Use the Cloud Storage instance associated with this context
const desertRef = ref(alice.storage(), 'images/desert.jpg');
await assertSucceeds(deleteObject(desertRef));

RulesTestEnvironment.withSecurityRulesDisabled()

এমন একটি কনটেক্সট সহ টেস্ট সেট-আপ ফাংশন রান করুন যা এমনভাবে কাজ করে যেন নিরাপত্তা সংক্রান্ত নিয়ম বন্ধ করা আছে।

এই পদ্ধতিতে একটি কলব্যাক ফাংশন ব্যবহার করা হয়, যা নিরাপত্তা-নিয়ম-বাইপাসিং কনটেক্সট ব্যবহার করে এবং একটি প্রতিশ্রুতি দেয়। The context will be destroyed once the promise resolves / rejects.

RulesTestEnvironment.cleanup()

এই পদ্ধতি টেস্ট এনভায়রনমেন্টে তৈরি করা সব RulesTestContexts নষ্ট করে দেয় এবং অন্তর্নিহিত রিসোর্স পরিষ্কার করে দেয়, যার ফলে পরিষ্কারভাবে বেরিয়ে আসা যায়।

এই পদ্ধতি কোনওভাবেই এমুলেটরের স্ট্যাটাস পরিবর্তন করে না। পরীক্ষার মধ্যে ডেটা রিসেট করতে, অ্যাপ্লিকেশন ইমুলেটর-নির্দিষ্ট ডেটা মোছার পদ্ধতি ব্যবহার করুন।

assertSucceeds(pr: Promise<any>)) => Promise<any>

এটি একটি টেস্ট কেস ইউটিলিটি ফাংশন।

ফাংশনটি দাবি করে যে এমুলেটর অপারেশনকে র‍্যাপ করা প্রদত্ত প্রমিস কোনও নিরাপত্তা নিয়ম লঙ্ঘন ছাড়াই সমাধান করা হবে।

await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });

assertFails(pr: Promise<any>)) => Promise<any>

এটি একটি টেস্ট কেস ইউটিলিটি ফাংশন।

ফাংশনটি দাবি করে যে এমুলেটর অপারেশন র‍্যাপ করা সাপ্লাই করা প্রমিস নিরাপত্তা নিয়ম লঙ্ঘনের সাথে প্রত্যাখ্যান করা হবে।

await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });

ইমুলেটর-নির্দিষ্ট পদ্ধতি

এছাড়াও, v9 SDK-তে সাধারণ টেস্ট পদ্ধতি ও ইউটিলিটি ফাংশন দেখুন।

RulesTestEnvironment.clearFirestore() => Promise<void>

এই পদ্ধতি Firestore ডেটাবেসে থাকা ডেটা মুছে দেয় যা Firestore এমুলেটরের জন্য কনফিগার করা projectId-এর অন্তর্গত।

RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;

এই পদ্ধতি এই টেস্ট কনটেক্সটের জন্য Firestore ইনস্ট্যান্স পায়। ফেরত পাওয়া Firebase JS Client SDK ইনস্ট্যান্স ক্লায়েন্ট SDK API-এর (v9 মডুলার বা v9 কম্প্যাট) সাথে ব্যবহার করা যেতে পারে।

নিয়ম মূল্যায়ন ভিজ্যুয়ালাইজ করা

Cloud Firestore এমুলেটর আপনাকে এমুলেটর সুইট UI-তে ক্লায়েন্টের অনুরোধগুলি কল্পনা করতে দেয়, যার মধ্যে Firebase নিরাপত্তা নিয়মের জন্য মূল্যায়ন ট্রেসিং অন্তর্ভুক্ত রয়েছে।

প্রতিটি অনুরোধের জন্য বিস্তারিত মূল্যায়ন ক্রম দেখতে Firestore > অনুরোধ ট্যাব খুলুন।

Firestore Emulator Requests Monitor, নিরাপত্তা সংক্রান্ত নিয়মের মূল্যায়ন দেখাচ্ছে

পরীক্ষার রিপোর্ট তৈরি করা

একগুচ্ছ টেস্ট চালানোর পরে, আপনি টেস্ট কভারেজ রিপোর্ট অ্যাক্সেস করতে পারবেন যা দেখায় যে আপনার প্রতিটি নিরাপত্তা নিয়ম কীভাবে মূল্যায়ন করা হয়েছে।

রিপোর্ট পেতে, এমুলেটর চলাকালীন এতে এক্সপোজড এন্ডপয়েন্ট কোয়েরি করুন। ব্রাউজার-ফ্রেন্ডলি ভার্সনের জন্য, নিম্নলিখিত URL ব্যবহার করুন:

http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage.html

এটি আপনার নিয়মকে এক্সপ্রেশন ও সাব-এক্সপ্রেশনে ভাগ করে দেয়। আপনি মূল্যায়নের সংখ্যা ও রিটার্ন করা ভ্যালু সহ আরও তথ্য পেতে মাউসওভার করতে পারেন। এই ডেটার র JSON ভার্সনের জন্য, আপনার কোয়েরিতে নিম্নলিখিত URL অন্তর্ভুক্ত করুন:

http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage

এমুলেটর ও প্রোডাকশনের মধ্যে পার্থক্য

  1. আপনাকে আলাদা করে Cloud Firestore প্রোজেক্ট তৈরি করতে হবে না। অ্যাক্সেস করা হয়েছে এমন যেকোনও ইনস্ট্যান্স এমুলেটর অটোমেটিক তৈরি করে।
  2. Cloud Firestore এমুলেটর সাধারণ Firebase Authentication ফ্লোতে কাজ করে না। পরিবর্তে, Firebase Test SDK-তে, আমরা rules-unit-testing লাইব্রেরিতে initializeTestApp() পদ্ধতি প্রদান করেছি, যা একটি auth ফিল্ড নেয়। এই পদ্ধতি ব্যবহার করে তৈরি করা Firebase হ্যান্ডেল এমনভাবে কাজ করবে যেন এটি আপনার প্রদান করা যেকোনও এন্টিটি হিসেবে সফলভাবে যাচাই করা হয়েছে। আপনি null পাস করলে, এটি একজন যাচাই না করা ব্যবহারকারীর মতো আচরণ করবে (যেমন, auth != null নিয়ম কাজ করবে না)।

পরিচিত সমস্যার সমাধান করা

Cloud Firestore এমুলেটর ব্যবহার করার সময়, আপনি নিম্নলিখিত পরিচিত সমস্যার সম্মুখীন হতে পারেন। আপনি যে অনিয়মিত আচরণ লক্ষ্য করছেন, তার সমস্যা সমাধান করতে নিচে দেওয়া নির্দেশাবলী অনুসরণ করুন। এই নোটগুলি নিরাপত্তা সংক্রান্ত নিয়মের ইউনিট টেস্টিং লাইব্রেরির কথা মাথায় রেখে লেখা হয়েছে, তবে সাধারণ পদ্ধতি যেকোনও Firebase SDK-এর ক্ষেত্রে প্রযোজ্য।

টেস্টের আচরণে ধারাবাহিকতা নেই

আপনার টেস্ট যদি মাঝে মাঝে পাস এবং ফেল করে, এমনকি টেস্টে কোনও পরিবর্তন না করেও, আপনাকে যাচাই করতে হতে পারে যে সেগুলি সঠিকভাবে সাজানো হয়েছে কিনা। এমুলেটরের সাথে বেশিরভাগ ইন্টার‍্যাকশন অ্যাসিঙ্ক্রোনাস হয়, তাই সব অ্যাসিঙ্ক কোড সঠিকভাবে সাজানো আছে কিনা তা ডবল-চেক করুন। আপনি হয় প্রমিস চেইন করে অথবা await নোটেশন উদারভাবে ব্যবহার করে সিকোয়েন্সিং ঠিক করতে পারেন।

বিশেষ করে, নিম্নলিখিত অ্যাসিঙ্ক অপারেশন পর্যালোচনা করুন:

  • নিরাপত্তা সংক্রান্ত নিয়ম সেট করা, যেমন, initializeTestEnvironment।
  • ডেটা পড়া ও লেখা, যেমন, db.collection("users").doc("alice").get()-এর সাথে।
  • assertSucceeds এবং assertFails সহ অপারেশনাল অ্যাসার্শন।

আপনি প্রথমবার এমুলেটর লোড করার সময় শুধুমাত্র টেস্ট পাস করে

এমুলেটরটি স্টেটফুল। এটি মেমরিতে লেখা সমস্ত ডেটা স্টোর করে, তাই এমুলেটর বন্ধ হয়ে গেলে যেকোনও ডেটা হারিয়ে যায়। আপনি যদি একই প্রোজেক্ট আইডির জন্য একাধিক টেস্ট চালান, তাহলে প্রতিটি টেস্ট এমন ডেটা তৈরি করতে পারে যা পরবর্তী টেস্টগুলিকে প্রভাবিত করতে পারে। এই আচরণ বাইপাস করতে আপনি নিম্নলিখিত যেকোনও পদ্ধতি ব্যবহার করতে পারেন:

  • প্রতিটি পরীক্ষার জন্য অনন্য প্রোজেক্ট আইডি ব্যবহার করুন। মনে রাখবেন যে আপনি এটি করার সিদ্ধান্ত নিলে, আপনাকে প্রতিটি পরীক্ষার অংশ হিসেবে initializeTestEnvironment-এ কল করতে হবে; নিয়মগুলি শুধুমাত্র ডিফল্ট প্রোজেক্ট আইডির জন্য অটোমেটিক লোড করা হয়।
  • আপনার টেস্টগুলি পুনর্গঠন করুন যাতে সেগুলি আগে লেখা ডেটার সাথে ইন্টার‍্যাক্ট না করে (যেমন, প্রতিটি টেস্টের জন্য একটি আলাদা সংগ্রহ ব্যবহার করুন)।
  • পরীক্ষা চলাকালীন লেখা সব ডেটা মুছে দিন।

টেস্ট সেট-আপ করা খুব জটিল

আপনার টেস্ট সেট-আপ করার সময়, আপনি এমনভাবে ডেটা পরিবর্তন করতে চাইতে পারেন যা আপনার Cloud Firestore Security Rules আসলে অনুমতি দেয় না। আপনার নিয়মগুলি টেস্ট সেট-আপকে জটিল করে তুললে, সেট-আপের ধাপগুলিতে RulesTestEnvironment.withSecurityRulesDisabled ব্যবহার করে দেখুন, যাতে রিড ও রাইট অপারেশন PERMISSION_DENIED সংক্রান্ত সমস্যা ট্রিগার না করে।

তারপরে, আপনার টেস্ট যথাক্রমে RulesTestEnvironment.authenticatedContext এবং unauthenticatedContext ব্যবহার করে যাচাইকৃত বা যাচাই না করা ব্যবহারকারী হিসেবে অপারেশন করতে পারে। এটি আপনাকে যাচাই করতে দেয় যে আপনার Cloud Firestore Security Rules বিভিন্ন ক্ষেত্রে সঠিকভাবে অনুমতি দেয় / অস্বীকার করে।