Cloud Firestore सुरक्षा नियम लिखने की शर्तें

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

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

प्रमाणीकरण

सबसे आम सुरक्षा नियम पैटर्न में से एक उपयोगकर्ता की प्रमाणीकरण स्थिति के आधार पर पहुंच को नियंत्रित करना है। उदाहरण के लिए, हो सकता है कि आपका ऐप केवल साइन-इन किए हुए उपयोगकर्ताओं को डेटा लिखने की अनुमति देना चाहे:

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow the user to access documents in the "cities" collection
    // only if they are authenticated.
    match /cities/{city} {
      allow read, write: if request.auth != null;
    }
  }
}

एक अन्य सामान्य पैटर्न यह सुनिश्चित करना है कि उपयोगकर्ता केवल अपना डेटा पढ़ और लिख सकें:

service cloud.firestore {
  match /databases/{database}/documents {
    // Make sure the uid of the requesting user matches name of the user
    // document. The wildcard expression {userId} makes the userId variable
    // available in rules.
    match /users/{userId} {
      allow read, update, delete: if request.auth != null && request.auth.uid == userId;
      allow create: if request.auth != null;
    }
  }
}

अगर आपका ऐप Firebase प्रमाणीकरण या Google क्लाउड पहचान प्लेटफ़ॉर्म का उपयोग करता है, तो request.auth वैरिएबल में डेटा का अनुरोध करने वाले क्लाइंट के लिए प्रमाणीकरण जानकारी होती है। request.auth के बारे में अधिक जानकारी के लिए , संदर्भ दस्तावेज़ देखें।

आंकड़ा मान्यीकरण

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

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow the user to read data if the document has the 'visibility'
    // field set to 'public'
    match /cities/{city} {
      allow read: if resource.data.visibility == 'public';
    }
  }
}

resource चर अनुरोधित दस्तावेज़ को संदर्भित करता है, और resource.data । डेटा दस्तावेज़ में संग्रहीत सभी फ़ील्ड और मानों का मानचित्र है। resource चर के बारे में अधिक जानकारी के लिए , संदर्भ दस्तावेज़ देखें।

डेटा लिखते समय, आप आने वाले डेटा की मौजूदा डेटा से तुलना करना चाह सकते हैं। इस स्थिति में, यदि आपका नियम सेट लंबित लेखन की अनुमति देता है, तो request.resource चर में दस्तावेज़ की भविष्य की स्थिति होती है। update संचालन के लिए जो केवल दस्तावेज़ फ़ील्ड के सबसेट को संशोधित करता है, request.resource चर में कार्रवाई के बाद लंबित दस्तावेज़ स्थिति होगी। अवांछित या असंगत डेटा अपडेट को रोकने के लिए आप request.resource में फ़ील्ड मानों की जांच कर सकते हैं:

service cloud.firestore {
  match /databases/{database}/documents {
    // Make sure all cities have a positive population and
    // the name is not changed
    match /cities/{city} {
      allow update: if request.resource.data.population > 0
                    && request.resource.data.name == resource.data.name;
    }
  }
}

अन्य दस्तावेज़ों तक पहुँचें

get() और exists() फ़ंक्शन का उपयोग करके, आपके सुरक्षा नियम डेटाबेस में अन्य दस्तावेज़ों के विरुद्ध आने वाले अनुरोधों का मूल्यांकन कर सकते हैं। get() और exists() फ़ंक्शन दोनों पूरी तरह से निर्दिष्ट दस्तावेज़ पथ की अपेक्षा करते हैं। गेट get() और exists() के लिए पथ बनाने के लिए चर का उपयोग करते समय, आपको $(variable) सिंटैक्स का उपयोग करके चर से स्पष्ट रूप से बचने की आवश्यकता होती है।

नीचे दिए गए उदाहरण में, database वैरिएबल को मैच स्टेटमेंट match /databases/{database}/documents द्वारा कैप्चर किया जाता है और पथ बनाने के लिए उपयोग किया जाता है:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      // Make sure a 'users' document exists for the requesting user before
      // allowing any writes to the 'cities' collection
      allow create: if request.auth != null && exists(/databases/$(database)/documents/users/$(request.auth.uid))

      // Allow the user to delete cities if their user document has the
      // 'admin' field set to 'true'
      allow delete: if request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true
    }
  }
}

लिखने के लिए, आप लेन-देन या बैच के पूरा होने के बाद दस्तावेज़ की स्थिति तक पहुँचने के लिए getAfter() फ़ंक्शन का उपयोग कर सकते हैं, लेकिन लेन-देन या बैच के आने से पहले। get() की तरह, getAfter() फ़ंक्शन पूरी तरह से निर्दिष्ट दस्तावेज़ पथ लेता है। आप लेन-देन या बैच के रूप में एक साथ होने वाले लेखन के सेट को परिभाषित करने के लिए getAfter() का उपयोग कर सकते हैं।

एक्सेस कॉल सीमा

प्रति नियम सेट मूल्यांकन दस्तावेज़ एक्सेस कॉल की एक सीमा है:

  • 10 एकल-दस्तावेज़ अनुरोधों और क्वेरी अनुरोधों के लिए।
  • 20 बहु-दस्तावेज़ पढ़ने, लेनदेन और बैच लिखने के लिए। 10 की पिछली सीमा भी प्रत्येक ऑपरेशन पर लागू होती है।

    उदाहरण के लिए, कल्पना करें कि आप 3 लेखन कार्यों के साथ एक बैच लिखने का अनुरोध बनाते हैं और आपके सुरक्षा नियम प्रत्येक लेखन को मान्य करने के लिए 2 दस्तावेज़ एक्सेस कॉल का उपयोग करते हैं। इस मामले में, प्रत्येक लेखन अपने 10 एक्सेस कॉलों में से 2 का उपयोग करता है और बैच लिखने का अनुरोध इसके 20 एक्सेस कॉलों में से 6 का उपयोग करता है।

किसी भी सीमा से अधिक होने पर अनुमति अस्वीकृत त्रुटि हो जाती है। कुछ दस्तावेज़ एक्सेस कॉल को कैश किया जा सकता है, और कैश्ड कॉल को सीमा में नहीं गिना जाता है।

ये सीमाएँ लेन-देन और बैच लेखन को कैसे प्रभावित करती हैं, इसकी विस्तृत व्याख्या के लिए, परमाणु संचालन को सुरक्षित करने के लिए मार्गदर्शिका देखें।

एक्सेस कॉल और मूल्य निर्धारण

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

कस्टम कार्य

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

  • फ़ंक्शंस में केवल एक return स्टेटमेंट हो सकता है। उनमें कोई अतिरिक्त तर्क नहीं हो सकता। उदाहरण के लिए, वे लूप निष्पादित नहीं कर सकते हैं या बाहरी सेवाओं को कॉल नहीं कर सकते हैं।
  • फ़ंक्शंस स्वचालित रूप से फ़ंक्शंस और वेरिएबल्स को उस दायरे से एक्सेस कर सकते हैं जिसमें उन्हें परिभाषित किया गया है। उदाहरण के लिए, service cloud.firestore स्कोप के भीतर परिभाषित एक फंक्शन के पास resource वेरिएबल और बिल्ट-इन फंक्शन्स जैसे कि get() और exists() तक पहुंच है।
  • फ़ंक्शंस अन्य फ़ंक्शंस को कॉल कर सकते हैं लेकिन रिकर्स नहीं कर सकते हैं। कुल कॉल स्टैक गहराई 10 तक सीमित है।
  • नियम संस्करण v2 में, फ़ंक्शन let कीवर्ड का उपयोग करके चर को परिभाषित कर सकते हैं। फ़ंक्शंस में अधिकतम 10 लेट बाइंडिंग हो सकते हैं, लेकिन रिटर्न स्टेटमेंट के साथ समाप्त होना चाहिए।

एक फ़ंक्शन को function कीवर्ड के साथ परिभाषित किया जाता है और शून्य या अधिक तर्क लेता है। उदाहरण के लिए, आप उपरोक्त उदाहरणों में प्रयुक्त दो प्रकार की स्थितियों को एक फ़ंक्शन में संयोजित करना चाह सकते हैं:

service cloud.firestore {
  match /databases/{database}/documents {
    // True if the user is signed in or the requested data is 'public'
    function signedInOrPublic() {
      return request.auth.uid != null || resource.data.visibility == 'public';
    }

    match /cities/{city} {
      allow read, write: if signedInOrPublic();
    }

    match /users/{user} {
      allow read, write: if signedInOrPublic();
    }
  }
}

जैसे-जैसे आपके नियमों की जटिलता बढ़ती है, आपके सुरक्षा नियमों में फ़ंक्शंस का उपयोग करना उन्हें अधिक बनाए रखने योग्य बनाता है।

नियम फिल्टर नहीं हैं

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

उदाहरण के लिए, निम्नलिखित सुरक्षा नियम लें:

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow the user to read data if the document has the 'visibility'
    // field set to 'public'
    match /cities/{city} {
      allow read: if resource.data.visibility == 'public';
    }
  }
}

अस्वीकृत : यह नियम निम्नलिखित क्वेरी को अस्वीकार करता है क्योंकि परिणाम सेट में ऐसे दस्तावेज़ शामिल हो सकते हैं जहां visibility public नहीं है:

वेब
db.collection("cities").get()
    .then(function(querySnapshot) {
        querySnapshot.forEach(function(doc) {
            console.log(doc.id, " => ", doc.data());
    });
});

अनुमति है: यह नियम निम्नलिखित क्वेरी की अनुमति देता है क्योंकि where("visibility", "==", "public") खंड गारंटी देता है कि परिणाम सेट नियम की स्थिति को संतुष्ट करता है:

वेब
db.collection("cities").where("visibility", "==", "public").get()
    .then(function(querySnapshot) {
        querySnapshot.forEach(function(doc) {
            console.log(doc.id, " => ", doc.data());
        });
    });

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

अगले कदम