इस गाइड में, सुरक्षा नियमों को स्ट्रक्चर करने के बारे में बताने वाली गाइड के आधार पर, Cloud Firestore Security Rules में शर्तें जोड़ने का तरीका बताया गया है. अगर आपको Cloud Firestore Security Rules की बुनियादी जानकारी नहीं है, तो शुरू करने के लिए गाइड देखें.
Cloud Firestore Security Rules का मुख्य बिल्डिंग ब्लॉक, शर्त होती है. शर्त, बूलियन एक्सप्रेशन होती है. इससे यह तय होता है कि किसी खास कार्रवाई की अनुमति दी जानी चाहिए या नहीं. सुरक्षा नियमों का इस्तेमाल करके, ऐसी शर्तें लिखी जा सकती हैं जिनसे उपयोगकर्ता की पुष्टि की जाती है, आने वाले डेटा की पुष्टि की जाती है या यहां तक कि आपके डेटाबेस के अन्य हिस्सों को ऐक्सेस किया जाता है.
पुष्टि करना
सुरक्षा नियमों के सबसे आम पैटर्न में से एक, उपयोगकर्ता की पुष्टि की स्थिति के आधार पर ऐक्सेस को कंट्रोल करना है. उदाहरण के लिए, हो सकता है कि आपका ऐप्लिकेशन, सिर्फ़ साइन इन किए हुए उपयोगकर्ताओं को डेटा लिखने की अनुमति देना चाहे:
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 Cloud Identity प्लैटफ़ॉर्म का इस्तेमाल करता है, तो request.auth वैरिएबल में
डेटा का अनुरोध करने वाले क्लाइंट की पुष्टि से जुड़ी जानकारी होती है.
request.auth के बारे में ज़्यादा जानकारी के लिए, रेफ़रंस
दस्तावेज़ देखें.
डेटा सत्यापन
कई ऐप्लिकेशन, डेटाबेस में मौजूद दस्तावेज़ों में फ़ील्ड के तौर पर, ऐक्सेस कंट्रोल की जानकारी सेव करते हैं. Cloud Firestore Security Rules दस्तावेज़ डेटा के आधार पर डाइनैमिक तरीके से ऐक्सेस की अनुमति दे सकते हैं या उसे अस्वीकार कर सकते हैं:
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 की पिछली सीमा भी लागू होती है.
उदाहरण के लिए, मान लें कि आपने लिखे जाने वाले डेटा के बैच का अनुरोध किया है. इसमें लिखे जाने वाले डेटा की तीन कार्रवाइयां शामिल हैं. साथ ही, आपके सुरक्षा नियम, लिखे जाने वाले हर डेटा की पुष्टि करने के लिए, दस्तावेज़ के ऐक्सेस कॉल का दो बार इस्तेमाल करते हैं. ऐसे में, लिखे जाने वाले हर डेटा के लिए, 10 में से दो ऐक्सेस कॉल का इस्तेमाल किया जाता है. वहीं, लिखे जाने वाले डेटा के बैच के अनुरोध के लिए, 20 में से छह ऐक्सेस कॉल का इस्तेमाल किया जाता है.
किसी भी सीमा से ज़्यादा होने पर, अनुमति नहीं होने की गड़बड़ी दिखती है. दस्तावेज़ के ऐक्सेस के कुछ कॉल को कैश किया जा सकता है. कैश किए गए कॉल, सीमाओं में नहीं गिने जाते.
इन सीमाओं से लेन-देन और बैच में लिखे जाने वाले डेटा पर कैसे असर पड़ता है, इस बारे में ज़्यादा जानने के लिए, एटॉमिक कार्रवाइयों को सुरक्षित करने के बारे में बताने वाली गाइड देखें.
ऐक्सेस कॉल और कीमत
इन फ़ंक्शन का इस्तेमाल करने से, आपके डेटाबेस में पढ़ने की कार्रवाई होती है. इसका मतलब है कि दस्तावेज़ों को पढ़ने के लिए आपसे शुल्क लिया जाएगा. भले ही, आपके नियम अनुरोध को अस्वीकार कर दें. बिलिंग की ज़्यादा जानकारी के लिए, Cloud Firestore की कीमत देखें.
पसंद के मुताबिक फ़ंक्शन
सुरक्षा नियम ज़्यादा जटिल होने पर, हो सकता है कि आपको शर्तों के सेट को ऐसे फ़ंक्शन में रैप करना पड़े जिन्हें नियमों के सेट में फिर से इस्तेमाल किया जा सके. सुरक्षा नियम, पसंद के मुताबिक फ़ंक्शन के साथ काम करते हैं. पसंद के मुताबिक फ़ंक्शन का सिंटैक्स, JavaScript की तरह होता है. हालांकि, सुरक्षा नियमों के फ़ंक्शन, डोमेन के हिसाब से तय की गई भाषा में लिखे जाते हैं. इसकी कुछ अहम सीमाएं होती हैं:
- फ़ंक्शन में सिर्फ़ एक
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(); } } }
सुरक्षा नियमों में फ़ंक्शन का इस्तेमाल करने से, नियमों की जटिलता बढ़ने पर भी उन्हें मैनेज करना आसान हो जाता है.
नियम, फ़िल्टर नहीं होते
डेटा को सुरक्षित करने और क्वेरी लिखने के बाद, इस बात का ध्यान रखें कि सुरक्षा नियम, फ़िल्टर नहीं होते. किसी कलेक्शन में मौजूद सभी दस्तावेज़ों के लिए क्वेरी नहीं लिखी जा सकती. साथ ही, यह उम्मीद नहीं की जा सकती कि Cloud Firestore सिर्फ़ उन दस्तावेज़ों को लौटाएगा जिन्हें मौजूदा क्लाइंट ऐक्सेस कर सकता है.
उदाहरण के लिए, सुरक्षा के इस नियम को देखें:
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 सुरक्षा नियम, हर क्वेरी का आकलन, उसके संभावित नतीजे के हिसाब से करते हैं. अगर क्वेरी से ऐसा दस्तावेज़ मिल सकता है जिसे क्लाइंट के पास पढ़ने की अनुमति नहीं है, तो अनुरोध अस्वीकार कर दिया जाता है. क्वेरी, सुरक्षा नियमों से तय की गई पाबंदियों के मुताबिक होनी चाहिए. सुरक्षा नियमों और क्वेरी के बारे में ज़्यादा जानने के लिए, डेटा को सुरक्षित तरीके से क्वेरी करना लेख पढ़ें.
अगले चरण
- जानें कि सुरक्षा नियमों से आपकी क्वेरी पर कैसे असर पड़ता है.
- जानें कि सुरक्षा नियमों को कैसे स्ट्रक्चर किया जाता है.
- सुरक्षा नियमों का रेफ़रंस पढ़ें.
- Cloud Storage for Firebase का इस्तेमाल करने वाले अपने ऐप्लिकेशन के लिए, लिखने Cloud Storage Security Rules का तरीका जानें जिनसे Cloud Firestore दस्तावेज़ों को ऐक्सेस किया जा सके.