क्लाउड फायरस्टोर सुरक्षा नियमों के लिए लेखन शर्तें

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

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

प्रमाणीकरण

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

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;
    }
  }
}

यदि आपका ऐप फायरबेस प्रमाणीकरण या 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());
        });
    });

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

अगले कदम