Cloud Firestore के सुरक्षा नियमों का स्ट्रक्चर तैयार करना

Cloud Firestore Security Rules की मदद से, अपने डेटाबेस में मौजूद दस्तावेज़ों और कलेक्शन का ऐक्सेस कंट्रोल किया जा सकता है. नियमों के सिंटैक्स की मदद से, ऐसे नियम बनाए जा सकते हैं जो किसी भी चीज़ से मैच करते हों. जैसे, पूरे डेटाबेस में किए गए सभी बदलावों से लेकर, किसी खास दस्तावेज़ पर किए गए सभी बदलावों तक.

इस गाइड में, सुरक्षा नियमों के बुनियादी सिंटैक्स और स्ट्रक्चर के बारे में बताया गया है. पूरे नियमों का सेट बनाने के लिए, इस सिंटैक्स को सुरक्षा नियमों की शर्तों के साथ जोड़ें.

सेवा और डेटाबेस से जुड़ा एलान

Cloud Firestore Security Rules हमेशा इस एलान से शुरू करें:

service cloud.firestore {
  match /databases/{database}/documents {
    // ...
  }
}

service cloud.firestore एलान में, Cloud Firestore के लिए नियमों का दायरा तय किया गया है. इससे, Cloud Firestore Security Rules और Cloud Storage जैसे दूसरे प्रॉडक्ट के नियमों के बीच विरोधाभास को रोका जा सकता है.

match /databases/{database}/documents एलान में बताया गया है कि नियम, प्रोजेक्ट में मौजूद किसी भी Cloud Firestore डेटाबेस से मेल खाने चाहिए. फ़िलहाल, हर प्रोजेक्ट में (default) नाम का सिर्फ़ एक डेटाबेस होता है.

पढ़ने/लिखने के बुनियादी नियम

बुनियादी नियमों में, दस्तावेज़ के पाथ की जानकारी देने वाला match स्टेटमेंट और तय किए गए डेटा को पढ़ने की अनुमति कब है, इसकी जानकारी देने वाला allow एक्सप्रेशन शामिल होता है:

service cloud.firestore {
  match /databases/{database}/documents {

    // Match any document in the 'cities' collection
    match /cities/{city} {
      allow read: if <condition>;
      allow write: if <condition>;
    }
  }
}

मैच करने वाले सभी स्टेटमेंट, दस्तावेज़ों पर ले जाने चाहिए, न कि कलेक्शन पर. मैच स्टेटमेंट, match /cities/SF की तरह किसी खास दस्तावेज़ पर ले जा सकता है या match /cities/{city} की तरह दिए गए पाथ में मौजूद किसी भी दस्तावेज़ पर ले जाने के लिए वाइल्डकार्ड का इस्तेमाल कर सकता है.

ऊपर दिए गए उदाहरण में, मैच स्टेटमेंट में {city} वाइल्डकार्ड सिंटैक्स का इस्तेमाल किया गया है. इसका मतलब है कि यह नियम cities कलेक्शन के किसी भी दस्तावेज़ पर लागू होता है, जैसे कि /cities/SF या /cities/NYC. जब मैच स्टेटमेंट में allow एक्सप्रेशन का आकलन किया जाता है, तो city वैरिएबल, शहर के दस्तावेज़ के नाम पर सेट हो जाएगा. जैसे, SF या NYC.

ज़्यादा जानकारी वाली कार्रवाइयां

कुछ मामलों में, read और write को ज़्यादा बारीक ऑपरेशन में बांटना फ़ायदेमंद होता है. उदाहरण के लिए, हो सकता है कि आपका ऐप्लिकेशन दस्तावेज़ बनाने के लिए, दस्तावेज़ मिटाने के लिए तय की गई शर्तों से अलग शर्तें लागू करना चाहे. इसके अलावा, हो सकता है कि आप एक दस्तावेज़ को पढ़ने की अनुमति देना चाहें, लेकिन बड़ी क्वेरी को अनुमति न दें.

read नियम को get और list में बांटा जा सकता है, जबकि write नियम को create, update, और delete में बांटा जा सकता है:

service cloud.firestore {
  match /databases/{database}/documents {
    // A read rule can be divided into get and list rules
    match /cities/{city} {
      // Applies to single document read requests
      allow get: if <condition>;

      // Applies to queries and collection read requests
      allow list: if <condition>;
    }

    // A write rule can be divided into create, update, and delete rules
    match /cities/{city} {
      // Applies to writes to nonexistent documents
      allow create: if <condition>;

      // Applies to writes to existing documents
      allow update: if <condition>;

      // Applies to delete operations
      allow delete: if <condition>;
    }
  }
}

हैरारकी वाला डेटा

Cloud Firestore में डेटा को दस्तावेज़ों के कलेक्शन में व्यवस्थित किया जाता है. साथ ही, हर दस्तावेज़ में सब-कलेक्शन की मदद से हैरारकी को बढ़ाया जा सकता है. यह समझना ज़रूरी है कि सुरक्षा नियम, हैरारकी वाले डेटा के साथ कैसे इंटरैक्ट करते हैं.

मान लें कि cities कलेक्शन के हर दस्तावेज़ में एक landmarks सब-कलेक्शन है. सुरक्षा से जुड़े नियम सिर्फ़ मैच होने वाले पाथ पर लागू होते हैं. इसलिए, cities कलेक्शन पर तय किए गए ऐक्सेस कंट्रोल, landmarks सब-कलेक्शन पर लागू नहीं होते. इसके बजाय, सब-कलेक्शन के ऐक्सेस को कंट्रोल करने के लिए साफ़ तौर पर नियम लिखें:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      allow read, write: if <condition>;

        // Explicitly define rules for the 'landmarks' subcollection
        match /landmarks/{landmark} {
          allow read, write: if <condition>;
        }
    }
  }
}

match स्टेटमेंट को नेस्ट करते समय, अंदरूनी match स्टेटमेंट का पाथ, हमेशा बाहरी match स्टेटमेंट के पाथ के हिसाब से होता है. इसलिए, ये नियमों के सेट एक जैसे हैं:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      match /landmarks/{landmark} {
        allow read, write: if <condition>;
      }
    }
  }
}
service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city}/landmarks/{landmark} {
      allow read, write: if <condition>;
    }
  }
}

बार-बार इस्तेमाल होने वाले वाइल्डकार्ड

अगर आपको किसी भी तरह की हैरारकी पर नियम लागू करने हैं, तो {name=**} के रीकर्सिव वाइल्डकार्ड सिंटैक्स का इस्तेमाल करें. उदाहरण के लिए:

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

बार-बार इस्तेमाल होने वाले वाइल्डकार्ड सिंटैक्स का इस्तेमाल करने पर, वाइल्डकार्ड वैरिएबल में मैच होने वाला पूरा पाथ सेगमेंट शामिल होगा. भले ही, दस्तावेज़ किसी नेस्ट किए गए सबकलेक्शन में हो. उदाहरण के लिए, ऊपर दिए गए नियम, /cities/SF/landmarks/coit_tower में मौजूद दस्तावेज़ से मैच करेंगे. साथ ही, document वैरिएबल की वैल्यू SF/landmarks/coit_tower होगी.

हालांकि, ध्यान दें कि बार-बार इस्तेमाल होने वाले वाइल्डकार्ड का व्यवहार, नियमों के वर्शन पर निर्भर करता है.

वर्शन 1

सुरक्षा नियम, डिफ़ॉल्ट रूप से वर्शन 1 का इस्तेमाल करते हैं. पहले वर्शन में, बार-बार इस्तेमाल होने वाले वाइल्डकार्ड, एक या उससे ज़्यादा पाथ आइटम से मैच करते हैं. ये खाली पाथ से मेल नहीं खाते. इसलिए, match /cities/{city}/{document=**}, सब-कलेक्शन में मौजूद दस्तावेज़ों से मेल खाता है, लेकिन cities कलेक्शन में मौजूद दस्तावेज़ों से नहीं. वहीं, match /cities/{document=**}, cities कलेक्शन और सब-कलेक्शन, दोनों में मौजूद दस्तावेज़ों से मेल खाता है.

बार-बार इस्तेमाल होने वाले वाइल्डकार्ड, मैच स्टेटमेंट के आखिर में होने चाहिए.

वर्शन 2

सुरक्षा नियमों के वर्शन 2 में, बार-बार इस्तेमाल होने वाले वाइल्डकार्ड, शून्य या एक से ज़्यादा पाथ आइटम से मैच करते हैं. match/cities/{city}/{document=**}, किसी भी सबकलेक्शन के साथ-साथ cities कलेक्शन के दस्तावेज़ों से मेल खाता है.

आपको अपने सुरक्षा नियमों में सबसे ऊपर rules_version = '2'; जोड़कर, वर्शन 2 में ऑप्ट-इन करना होगा:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{city}/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

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

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the songs collection group
    match /{path=**}/songs/{song} {
      allow read, write: if <condition>;
    }
  }
}

अगर कलेक्शन ग्रुप क्वेरी का इस्तेमाल किया जाता है, तो आपको कलेक्शन ग्रुप क्वेरी को सुरक्षित करना लेख में बताए गए वर्शन 2 का इस्तेमाल करना होगा.

ओवरलैप होने वाले मैच स्टेटमेंट

ऐसा हो सकता है कि कोई दस्तावेज़, एक से ज़्यादा match स्टेटमेंट से मैच करे. अगर एक से ज़्यादा allow एक्सप्रेशन किसी अनुरोध से मैच करते हैं, तो ऐक्सेस तब दिया जाता है, जब कोई भी शर्त true हो:

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the 'cities' collection.
    match /cities/{city} {
      allow read, write: if false;
    }

    // Matches any document in the 'cities' collection or subcollections.
    match /cities/{document=**} {
      allow read, write: if true;
    }
  }
}

ऊपर दिए गए उदाहरण में, cities कलेक्शन में सभी रीड और राइट की अनुमति होगी, क्योंकि दूसरा नियम हमेशा true होता है. भले ही, पहला नियम हमेशा false हो.

सुरक्षा नियम की सीमाएं

सुरक्षा से जुड़े नियमों के साथ काम करते समय, इन सीमाओं का ध्यान रखें:

सीमा विवरण
हर अनुरोध के लिए, exists(), get(), और getAfter() कॉल की ज़्यादा से ज़्यादा संख्या
  • एक दस्तावेज़ के अनुरोध और क्वेरी के अनुरोध के लिए 10.
  • एक से ज़्यादा दस्तावेज़ों को पढ़ने, लेन-देन, और एक साथ कई दस्तावेज़ों में डेटा लिखने के लिए 20. हर ऑपरेशन पर, 10 की पिछली सीमा भी लागू होती है.

    उदाहरण के लिए, मान लें कि आपने एक साथ कई डेटा डालने का अनुरोध किया है. इसमें तीन डेटा डालने के ऑपरेशन हैं और आपके सुरक्षा नियम, हर डेटा डालने की पुष्टि करने के लिए, दस्तावेज़ के दो ऐक्सेस कॉल का इस्तेमाल करते हैं. इस मामले में, हर बार लिखने के लिए, 10 में से दो ऐक्सेस कॉल का इस्तेमाल किया जाता है. साथ ही, एक साथ कई बार लिखने के अनुरोध के लिए, 20 में से छह ऐक्सेस कॉल का इस्तेमाल किया जाता है.

इनमें से किसी भी सीमा को पार करने पर, 'अनुमति नहीं दी गई' गड़बड़ी का मैसेज दिखता है.

दस्तावेज़ के ऐक्सेस के कुछ अनुरोध कैश मेमोरी में सेव किए जा सकते हैं. कैश मेमोरी में सेव किए गए अनुरोधों की गिनती, अनुरोधों की सीमा में नहीं की जाती.

नेस्ट किए गए match स्टेटमेंट की ज़्यादा से ज़्यादा गहराई 10
नेस्ट किए गए match स्टेटमेंट के सेट में, पाथ सेगमेंट में पाथ की ज़्यादा से ज़्यादा लंबाई 100
नेस्ट किए गए match स्टेटमेंट के सेट में, पाथ कैप्चर वैरिएबल की ज़्यादा से ज़्यादा संख्या 20
फ़ंक्शन कॉल की ज़्यादा से ज़्यादा गहराई 20
फ़ंक्शन के आर्ग्युमेंट की ज़्यादा से ज़्यादा संख्या 7
हर फ़ंक्शन के लिए let वैरिएबल बाइंडिंग की ज़्यादा से ज़्यादा संख्या 10
बार-बार या चक्रीय तौर पर फ़ंक्शन कॉल करने की ज़्यादा से ज़्यादा संख्या 0 &lpar;अनुमति नहीं है&rpar;
हर अनुरोध के लिए, एक्सप्रेशन की ज़्यादा से ज़्यादा संख्या 1,000
नियमों के सेट का ज़्यादा से ज़्यादा साइज़ नियमों के सेट का साइज़, इन दो सीमाओं के अंदर होना चाहिए:
  • Firebase कंसोल से पब्लिश किए गए या firebase deploy का इस्तेमाल करके सीएलआई से पब्लिश किए गए, नियमों के टेक्स्ट सोर्स के साइज़ पर 256 केबी की सीमा.
  • Firebase, सोर्स को प्रोसेस करके उसे बैक-एंड पर चालू करता है. इस प्रोसेस के दौरान, 250 केबी तक के नियमों का कंपाइल किया गया सेट बनाया जाता है.

अगले चरण