अपने Cloud Firestore सुरक्षा नियमों का परीक्षण करें

जैसे ही आप अपना ऐप बना रहे हैं, हो सकता है कि आप अपने क्लाउड फायरस्टोर डेटाबेस तक पहुंच को लॉक करना चाहें। हालाँकि, लॉन्च करने से पहले, आपको अधिक सूक्ष्म क्लाउड फायरस्टोर सुरक्षा नियमों की आवश्यकता होगी। क्लाउड फायरस्टोर एमुलेटर के साथ, अपने ऐप की सामान्य सुविधाओं और व्यवहार को प्रोटोटाइप करने और परीक्षण करने के अलावा, आप यूनिट परीक्षण लिख सकते हैं जो आपके क्लाउड फायरस्टोर सुरक्षा नियमों के व्यवहार की जांच करते हैं।

जल्दी शुरू

सरल नियमों वाले कुछ बुनियादी परीक्षण मामलों के लिए, त्वरित प्रारंभ नमूना आज़माएँ।

क्लाउड फायरस्टोर सुरक्षा नियमों को समझें

जब आप मोबाइल और वेब क्लाइंट लाइब्रेरी का उपयोग करते हैं तो सर्वर रहित प्रमाणीकरण, प्राधिकरण और डेटा सत्यापन के लिए फायरबेस प्रमाणीकरण और क्लाउड फायरस्टोर सुरक्षा नियम लागू करें।

क्लाउड फायरस्टोर सुरक्षा नियमों में दो भाग शामिल हैं:

  1. एक match विवरण जो आपके डेटाबेस में दस्तावेज़ों की पहचान करता है।
  2. एक allow अभिव्यक्ति जो उन दस्तावेज़ों तक पहुंच को नियंत्रित करती है।

फायरबेस प्रमाणीकरण उपयोगकर्ताओं की साख को सत्यापित करता है और उपयोगकर्ता-आधारित और भूमिका-आधारित एक्सेस सिस्टम के लिए आधार प्रदान करता है।

क्लाउड फायरस्टोर मोबाइल/वेब क्लाइंट लाइब्रेरी से प्रत्येक डेटाबेस अनुरोध का किसी भी डेटा को पढ़ने या लिखने से पहले आपके सुरक्षा नियमों के अनुसार मूल्यांकन किया जाता है। यदि नियम किसी भी निर्दिष्ट दस्तावेज़ पथ तक पहुंच से इनकार करते हैं, तो संपूर्ण अनुरोध विफल हो जाता है।

क्लाउड फायरस्टोर सुरक्षा नियमों के साथ शुरुआत करें में क्लाउड फायरस्टोर सुरक्षा नियमों के बारे में और जानें।

एम्यूलेटर स्थापित करें

क्लाउड फायरस्टोर एमुलेटर स्थापित करने के लिए, फायरबेस सीएलआई का उपयोग करें और नीचे दिए गए कमांड को चलाएं:

firebase setup:emulators:firestore

एम्यूलेटर चलाएँ

अपनी कार्यशील निर्देशिका में फ़ायरबेस प्रोजेक्ट प्रारंभ करके प्रारंभ करें। फायरबेस सीएलआई का उपयोग करते समय यह एक सामान्य पहला कदम है।

firebase init

निम्नलिखित कमांड का उपयोग करके एमुलेटर प्रारंभ करें। एम्यूलेटर तब तक चलेगा जब तक आप प्रक्रिया को बंद नहीं कर देते:

firebase emulators:start --only firestore

कई मामलों में आप एमुलेटर शुरू करना चाहते हैं, एक टेस्ट सूट चलाना चाहते हैं, और फिर परीक्षण चलने के बाद एमुलेटर को बंद करना चाहते हैं। आप इसे emulators:exec कमांड का उपयोग करके आसानी से कर सकते हैं:

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

प्रारंभ होने पर एमुलेटर डिफ़ॉल्ट पोर्ट (8080) पर चलने का प्रयास करेगा। आप अपनी firebase.json फ़ाइल के "emulators" अनुभाग को संशोधित करके एमुलेटर पोर्ट को बदल सकते हैं:

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

एम्यूलेटर चलाने से पहले

इससे पहले कि आप एमुलेटर का उपयोग शुरू करें, निम्नलिखित बातों का ध्यान रखें:

  • एमुलेटर प्रारंभ में आपकी firebase.json फ़ाइल के firestore.rules फ़ील्ड में निर्दिष्ट नियमों को लोड करेगा। यह आपके क्लाउड फायरस्टोर सुरक्षा नियमों वाली एक स्थानीय फ़ाइल के नाम की अपेक्षा करता है और उन नियमों को सभी परियोजनाओं पर लागू करता है। यदि आप स्थानीय फ़ाइल पथ प्रदान नहीं करते हैं या नीचे बताए अनुसार loadFirestoreRules विधि का उपयोग नहीं करते हैं, तो एमुलेटर सभी परियोजनाओं को खुले नियमों के रूप में मानता है।
  • जबकि अधिकांश फायरबेस एसडीके सीधे एमुलेटर के साथ काम करते हैं, केवल @firebase/rules-unit-testing लाइब्रेरी सुरक्षा नियमों में मॉकिंग auth समर्थन करती है, जिससे यूनिट परीक्षण बहुत आसान हो जाता है। इसके अलावा, लाइब्रेरी नीचे सूचीबद्ध सभी डेटा को साफ़ करने जैसी कुछ एमुलेटर-विशिष्ट सुविधाओं का समर्थन करती है।
  • एमुलेटर क्लाइंट एसडीके के माध्यम से प्रदान किए गए उत्पादन फायरबेस ऑथ टोकन को भी स्वीकार करेंगे और तदनुसार नियमों का मूल्यांकन करेंगे, जो आपके एप्लिकेशन को एकीकरण और मैन्युअल परीक्षणों में एमुलेटर से सीधे कनेक्ट करने की अनुमति देता है।

स्थानीय इकाई परीक्षण चलाएँ

V9 JavaScript SDK के साथ स्थानीय इकाई परीक्षण चलाएँ

फायरबेस अपने संस्करण 9 जावास्क्रिप्ट एसडीके और इसके संस्करण 8 एसडीके दोनों के साथ एक सुरक्षा नियम इकाई परीक्षण लाइब्रेरी वितरित करता है। लाइब्रेरी एपीआई काफी भिन्न हैं। हम v9 परीक्षण लाइब्रेरी की अनुशंसा करते हैं, जो अधिक सुव्यवस्थित है और एमुलेटर से कनेक्ट करने के लिए कम सेटअप की आवश्यकता होती है और इस प्रकार उत्पादन संसाधनों के आकस्मिक उपयोग से सुरक्षित रूप से बचा जा सकता है। पश्चगामी संगतता के लिए, हम v8 परीक्षण लाइब्रेरी उपलब्ध कराना जारी रखते हैं।

स्थानीय रूप से चलने वाले एमुलेटर के साथ इंटरैक्ट करने के लिए @firebase/rules-unit-testing मॉड्यूल का उपयोग करें। यदि आपको टाइमआउट या ECONNREFUSED त्रुटियां मिलती हैं, तो दोबारा जांचें कि एमुलेटर वास्तव में चल रहा है या नहीं।

हम दृढ़ता से Node.js के नवीनतम संस्करण का उपयोग करने की अनुशंसा करते हैं ताकि आप async/await नोटेशन का उपयोग कर सकें। आप जिन व्यवहारों का परीक्षण करना चाहते हैं उनमें से लगभग सभी में अतुल्यकालिक फ़ंक्शन शामिल हैं, और परीक्षण मॉड्यूल को प्रॉमिस-आधारित कोड के साथ काम करने के लिए डिज़ाइन किया गया है।

V9 रूल्स यूनिट टेस्टिंग लाइब्रेरी हमेशा एमुलेटर के प्रति सचेत रहती है और कभी भी आपके उत्पादन संसाधनों को नहीं छूती है।

आप 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 बनाती है, जो एक प्रमाणित प्रमाणीकरण उपयोगकर्ता की तरह व्यवहार करती है। लौटाए गए संदर्भ के माध्यम से बनाए गए अनुरोधों में एक नकली प्रमाणीकरण टोकन संलग्न होगा। वैकल्पिक रूप से, प्रमाणीकरण टोकन पेलोड के लिए कस्टम दावों या ओवरराइड्स को परिभाषित करने वाला ऑब्जेक्ट पास करें।

किसी भी कॉन्फ़िगर किए गए एमुलेटर इंस्टेंसेस तक पहुंचने के लिए अपने परीक्षणों में लौटाए गए टेस्ट संदर्भ ऑब्जेक्ट का उपयोग करें, जिसमें 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(), '/users/alice'), { ... });

RulesTestEnvironment.unauthenticatedContext() => RulesTestContext

यह विधि एक RulesTestContext बनाती है, जो एक ऐसे क्लाइंट की तरह व्यवहार करती है जो प्रमाणीकरण के माध्यम से लॉग इन नहीं है। लौटाए गए संदर्भ के माध्यम से बनाए गए अनुरोधों में फ़ायरबेस प्रामाणिक टोकन संलग्न नहीं होंगे।

किसी भी कॉन्फ़िगर किए गए एमुलेटर इंस्टेंसेस तक पहुंचने के लिए अपने परीक्षणों में लौटाए गए टेस्ट संदर्भ ऑब्जेक्ट का उपयोग करें, जिसमें 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()

एक संदर्भ के साथ एक परीक्षण सेटअप फ़ंक्शन चलाएँ जो ऐसा व्यवहार करता है मानो सुरक्षा नियम अक्षम कर दिए गए हों।

यह विधि एक कॉलबैक फ़ंक्शन लेती है, जो सुरक्षा-नियम-बायपासिंग संदर्भ लेती है और एक वादा लौटाती है। वादे के हल/अस्वीकार होते ही संदर्भ नष्ट हो जाएगा।

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>

यह विधि फायरस्टोर डेटाबेस में डेटा को साफ़ करती है जो फायरस्टोर एमुलेटर के लिए कॉन्फ़िगर किए गए projectId से संबंधित है।

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

इस विधि को इस परीक्षण संदर्भ के लिए फायरस्टोर उदाहरण मिलता है। लौटाए गए फायरबेस जेएस क्लाइंट एसडीके इंस्टेंस का उपयोग क्लाइंट एसडीके एपीआई (v9 मॉड्यूलर या वी9 कंपैट) के साथ किया जा सकता है।

नियमों के मूल्यांकन को विज़ुअलाइज़ करें

क्लाउड फायरस्टोर एमुलेटर आपको एमुलेटर सुइट यूआई में क्लाइंट अनुरोधों को देखने की सुविधा देता है, जिसमें फायरबेस सुरक्षा नियमों के लिए मूल्यांकन ट्रेसिंग भी शामिल है।

प्रत्येक अनुरोध के लिए विस्तृत मूल्यांकन अनुक्रम देखने के लिए फायरस्टोर > अनुरोध टैब खोलें।

फायरस्टोर एमुलेटर मॉनिटर से सुरक्षा नियम मूल्यांकन दिखाने का अनुरोध करता है

परीक्षण रिपोर्ट तैयार करें

परीक्षणों का एक सूट चलाने के बाद, आप परीक्षण कवरेज रिपोर्ट तक पहुंच सकते हैं जो दिखाती है कि आपके प्रत्येक सुरक्षा नियम का मूल्यांकन कैसे किया गया था।

रिपोर्ट प्राप्त करने के लिए, एम्यूलेटर के चलने के दौरान उस पर एक उजागर समापन बिंदु को क्वेरी करें। ब्राउज़र-अनुकूल संस्करण के लिए, निम्न URL का उपयोग करें:

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

यह आपके नियमों को अभिव्यक्तियों और उप-अभिव्यक्तियों में तोड़ देता है जिन्हें आप अधिक जानकारी के लिए माउसओवर कर सकते हैं, जिसमें मूल्यांकन की संख्या और लौटाए गए मान भी शामिल हैं। इस डेटा के कच्चे JSON संस्करण के लिए, अपनी क्वेरी में निम्नलिखित URL शामिल करें:

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

एम्यूलेटर और उत्पादन के बीच अंतर

  1. आपको स्पष्ट रूप से क्लाउड फायरस्टोर प्रोजेक्ट बनाने की आवश्यकता नहीं है। एमुलेटर स्वचालित रूप से एक्सेस किया गया कोई भी इंस्टेंस बनाता है।
  2. क्लाउड फायरस्टोर एमुलेटर सामान्य फायरबेस प्रमाणीकरण प्रवाह के साथ काम नहीं करता है। इसके बजाय, फायरबेस टेस्ट एसडीके में, हमने rules-unit-testing लाइब्रेरी में initializeTestApp() विधि प्रदान की है, जो एक auth फ़ील्ड लेती है। इस पद्धति का उपयोग करके बनाया गया फायरबेस हैंडल ऐसा व्यवहार करेगा जैसे कि आपने जो भी इकाई प्रदान की है, वह सफलतापूर्वक प्रमाणित हो गया है। यदि आप null पास करते हैं, तो यह एक अप्रमाणित उपयोगकर्ता के रूप में व्यवहार करेगा (उदाहरण के लिए, auth != null नियम विफल हो जाएंगे)।

ज्ञात समस्याओं का निवारण करें

जैसे ही आप क्लाउड फायरस्टोर एमुलेटर का उपयोग करते हैं, आपको निम्नलिखित ज्ञात समस्याओं का सामना करना पड़ सकता है। आपके द्वारा अनुभव किए जा रहे किसी भी अनियमित व्यवहार के निवारण के लिए नीचे दिए गए मार्गदर्शन का पालन करें। ये नोट्स सुरक्षा नियम इकाई परीक्षण लाइब्रेरी को ध्यान में रखकर लिखे गए हैं, लेकिन सामान्य दृष्टिकोण किसी भी फायरबेस एसडीके पर लागू होते हैं।

परीक्षण व्यवहार असंगत है

यदि आपके परीक्षण कभी-कभी उत्तीर्ण और असफल हो रहे हैं, यहां तक ​​कि परीक्षणों में कोई बदलाव किए बिना भी, आपको यह सत्यापित करने की आवश्यकता हो सकती है कि वे ठीक से अनुक्रमित हैं। एमुलेटर के साथ अधिकांश इंटरैक्शन एसिंक्रोनस हैं, इसलिए दोबारा जांच लें कि सभी एसिंक कोड ठीक से अनुक्रमित हैं। आप या तो वादों की श्रृंखला बनाकर, या उदारतापूर्वक await नोटेशन का उपयोग करके अनुक्रम को ठीक कर सकते हैं।

विशेष रूप से, निम्नलिखित async परिचालनों की समीक्षा करें:

  • उदाहरण के लिए, initializeTestEnvironment के साथ सुरक्षा नियम सेट करना।
  • उदाहरण के लिए, db.collection("users").doc("alice").get() के साथ डेटा पढ़ना और लिखना।
  • ऑपरेशनल दावे, जिनमें assertSucceeds और assertFails शामिल हैं।

परीक्षण केवल तभी पास होते हैं जब आप एमुलेटर को पहली बार लोड करते हैं

एम्यूलेटर स्टेटफुल है. यह इसमें लिखे गए सभी डेटा को मेमोरी में संग्रहीत करता है, इसलिए जब भी एमुलेटर बंद होता है तो कोई भी डेटा खो जाता है। यदि आप एक ही प्रोजेक्ट आईडी के विरुद्ध एकाधिक परीक्षण चला रहे हैं, तो प्रत्येक परीक्षण डेटा उत्पन्न कर सकता है जो बाद के परीक्षणों को प्रभावित कर सकता है। इस व्यवहार को बायपास करने के लिए आप निम्न में से किसी भी तरीके का उपयोग कर सकते हैं:

  • प्रत्येक परीक्षण के लिए अद्वितीय प्रोजेक्ट आईडी का उपयोग करें। ध्यान दें कि यदि आप ऐसा करना चुनते हैं तो आपको प्रत्येक परीक्षण के भाग के रूप में initializeTestEnvironment कॉल करने की आवश्यकता होगी; नियम केवल डिफ़ॉल्ट प्रोजेक्ट आईडी के लिए स्वचालित रूप से लोड होते हैं।
  • अपने परीक्षणों को पुनर्गठित करें ताकि वे पहले लिखे गए डेटा के साथ इंटरैक्ट न करें (उदाहरण के लिए, प्रत्येक परीक्षण के लिए एक अलग संग्रह का उपयोग करें)।
  • परीक्षण के दौरान लिखे गए सभी डेटा को हटा दें।

परीक्षण सेटअप बहुत जटिल है

अपना परीक्षण सेट करते समय, आप डेटा को इस तरह से संशोधित करना चाह सकते हैं जिसकी आपके क्लाउड फायरस्टोर सुरक्षा नियम वास्तव में अनुमति नहीं देते हैं। यदि आपके नियम परीक्षण सेटअप को जटिल बना रहे हैं, तो अपने सेटअप चरणों में RulesTestEnvironment.withSecurityRulesDisabled का उपयोग करने का प्रयास करें, ताकि पढ़ने और लिखने से PERMISSION_DENIED त्रुटियाँ ट्रिगर न हों।

उसके बाद, आपका परीक्षण क्रमशः RulesTestEnvironment.authenticatedContext और unauthenticatedContext का उपयोग करके एक प्रमाणित या अप्रमाणित उपयोगकर्ता के रूप में संचालन कर सकता है। यह आपको यह सत्यापित करने की अनुमति देता है कि आपके क्लाउड फायरस्टोर सुरक्षा नियम विभिन्न मामलों को सही ढंग से अनुमति/अस्वीकार करते हैं।