क्लाउड फायरस्टोर सुरक्षा नियम प्रश्नों के साथ कैसे इंटरैक्ट करते हैं, यह समझाने के लिए यह पेज स्ट्रक्चरिंग सिक्योरिटी रूल्स और राइटिंग कंडीशंस फॉर सिक्योरिटी रूल्स की अवधारणाओं पर आधारित है। यह बारीकी से देखता है कि सुरक्षा नियम उन प्रश्नों को कैसे प्रभावित करते हैं जिन्हें आप लिख सकते हैं और वर्णन करता है कि कैसे सुनिश्चित करें कि आपके प्रश्न आपके सुरक्षा नियमों के समान बाधाओं का उपयोग करते हैं। यह पृष्ठ यह भी बताता है कि limit
और orderBy
जैसे क्वेरी गुणों के आधार पर प्रश्नों को अनुमति देने या अस्वीकार करने के लिए सुरक्षा नियम कैसे लिखें।
नियम फ़िल्टर नहीं हैं
दस्तावेज़ प्राप्त करने के लिए प्रश्न लिखते समय, ध्यान रखें कि सुरक्षा नियम फ़िल्टर नहीं हैं—प्रश्न सभी या कुछ भी नहीं हैं। आपका समय और संसाधन बचाने के लिए, क्लाउड फायरस्टोर आपके सभी दस्तावेज़ों के वास्तविक फ़ील्ड मानों के बजाय इसके संभावित परिणाम सेट के विरुद्ध एक क्वेरी का मूल्यांकन करता है। यदि कोई क्वेरी संभावित रूप से उन दस्तावेज़ों को लौटा सकती है जिन्हें क्लाइंट को पढ़ने की अनुमति नहीं है, तो संपूर्ण अनुरोध विफल हो जाता है।
प्रश्न और सुरक्षा नियम
जैसा कि नीचे दिए गए उदाहरण प्रदर्शित करते हैं, आपको अपने सुरक्षा नियमों की बाधाओं को पूरा करने के लिए अपनी क्वेरी लिखनी चाहिए।
auth.uid
पर आधारित दस्तावेज़ों को सुरक्षित और क्वेरी करें
निम्न उदाहरण दर्शाता है कि सुरक्षा नियम द्वारा संरक्षित दस्तावेज़ों को पुनः प्राप्त करने के लिए क्वेरी कैसे लिखनी है। एक ऐसे डेटाबेस पर विचार करें जिसमें story
दस्तावेजों का संग्रह हो:
/कहानियां/{कहानीआईडी}
{
title: "A Great Story",
content: "Once upon a time...",
author: "some_auth_id",
published: false
}
title
और content
फ़ील्ड के अलावा, प्रत्येक दस्तावेज़ author
और published
फ़ील्ड को अभिगम नियंत्रण के लिए उपयोग करने के लिए संग्रहीत करता है। ये उदाहरण मानते हैं कि ऐप author
फ़ील्ड को दस्तावेज़ बनाने वाले उपयोगकर्ता के यूआईडी पर सेट करने के लिए फायरबेस प्रमाणीकरण का उपयोग करता है। फायरबेस ऑथेंटिकेशन भी सुरक्षा नियमों में request.auth
वैरिएबल को पॉप्युलेट करता है।
निम्नलिखित सुरक्षा नियम प्रत्येक story
के लेखक के लिए पढ़ने और लिखने की पहुंच को प्रतिबंधित करने के लिए request.auth
और resource.data
चर का उपयोग करता है:
service cloud.firestore {
match /databases/{database}/documents {
match /stories/{storyid} {
// Only the authenticated user who authored the document can read or write
allow read, write: if request.auth != null && request.auth.uid == resource.data.author;
}
}
}
मान लीजिए कि आपके ऐप में एक पृष्ठ शामिल है जो उपयोगकर्ता को उनके द्वारा लिखे गए story
दस्तावेज़ों की एक सूची दिखाता है। आप उम्मीद कर सकते हैं कि आप इस पेज को पॉप्युलेट करने के लिए निम्न क्वेरी का उपयोग कर सकते हैं। हालाँकि, यह क्वेरी विफल हो जाएगी, क्योंकि इसमें आपके सुरक्षा नियमों के समान बाधाएँ शामिल नहीं हैं:
अमान्य : क्वेरी बाधाएँ सुरक्षा नियमों की बाधाओं से मेल नहीं खातीं
// This query will fail
db.collection("stories").get()
क्वेरी विफल हो जाती है भले ही वर्तमान उपयोगकर्ता वास्तव में प्रत्येक story
दस्तावेज़ का लेखक हो। इस व्यवहार का कारण यह है कि जब क्लाउड फायरस्टोर आपके सुरक्षा नियमों को लागू करता है, तो यह क्वेरी का मूल्यांकन इसके संभावित परिणाम सेट के विरुद्ध करता है, न कि आपके डेटाबेस में दस्तावेज़ों के वास्तविक गुणों के विरुद्ध। यदि किसी क्वेरी में संभावित रूप से ऐसे दस्तावेज़ शामिल हो सकते हैं जो आपके सुरक्षा नियमों का उल्लंघन करते हैं, तो क्वेरी विफल हो जाएगी।
इसके विपरीत, निम्न क्वेरी सफल होती है, क्योंकि इसमें author
क्षेत्र पर सुरक्षा नियमों के समान प्रतिबंध शामिल हैं:
वैध : क्वेरी प्रतिबंध सुरक्षा नियमों की बाधाओं से मेल खाते हैं
var user = firebase.auth().currentUser;
db.collection("stories").where("author", "==", user.uid).get()
एक क्षेत्र के आधार पर दस्तावेजों को सुरक्षित और क्वेरी करें
प्रश्नों और नियमों के बीच परस्पर क्रिया को और अधिक प्रदर्शित करने के लिए, नीचे दिए गए सुरक्षा नियम stories
संग्रह के लिए पठन पहुंच का विस्तार करते हैं ताकि किसी भी उपयोगकर्ता को story
दस्तावेज़ पढ़ने की अनुमति मिल सके जहां published
फ़ील्ड को true
पर सेट किया गया हो।
service cloud.firestore {
match /databases/{database}/documents {
match /stories/{storyid} {
// Anyone can read a published story; only story authors can read unpublished stories
allow read: if resource.data.published == true || (request.auth != null && request.auth.uid == resource.data.author);
// Only story authors can write
allow write: if request.auth != null && request.auth.uid == resource.data.author;
}
}
}
प्रकाशित पृष्ठों की क्वेरी में सुरक्षा नियमों के समान प्रतिबंध शामिल होने चाहिए:
db.collection("stories").where("published", "==", true).get()
क्वेरी बाधा .where("published", "==", true)
गारंटी देती है कि किसी भी परिणाम के लिए resource.data.published
true
है। इसलिए, यह क्वेरी सुरक्षा नियमों को पूरा करती है और डेटा पढ़ने की अनुमति है।
OR
पूछताछ
किसी नियम-सेट के विरुद्ध तार्किक OR
क्वेरी ( or
, in
, या array-contains-any
) का मूल्यांकन करते समय, Cloud Firestore प्रत्येक तुलना मान का अलग-अलग मूल्यांकन करता है। प्रत्येक तुलना मूल्य को सुरक्षा नियम की कमी को पूरा करना चाहिए। उदाहरण के लिए, निम्नलिखित नियम के लिए:
match /mydocuments/{doc} {
allow read: if resource.data.x > 5;
}
अमान्य : क्वेरी सभी संभावित दस्तावेज़ों के लिए x > 5
गारंटी नहीं देती है
// These queries will fail
query(db.collection("mydocuments"),
or(where("x", "==", 1),
where("x", "==", 6)
)
)
query(db.collection("mydocuments"),
where("x", "in", [1, 3, 6, 42, 99])
)
मान्य : क्वेरी सभी संभावित दस्तावेज़ों के लिए x > 5
की गारंटी देती है
query(db.collection("mydocuments"),
or(where("x", "==", 6),
where("x", "==", 42)
)
)
query(db.collection("mydocuments"),
where("x", "in", [6, 42, 99, 105, 200])
)
प्रश्नों पर बाधाओं का मूल्यांकन
आपके सुरक्षा नियम प्रश्नों को उनकी बाधाओं के आधार पर स्वीकार या अस्वीकार भी कर सकते हैं। request.query
वेरिएबल में किसी क्वेरी की limit
, offset
और orderBy
विशेषताएँ होती हैं। उदाहरण के लिए, आपके सुरक्षा नियम किसी भी क्वेरी को अस्वीकार कर सकते हैं जो एक निश्चित सीमा तक पुनर्प्राप्त किए गए दस्तावेज़ों की अधिकतम संख्या को सीमित नहीं करता है:
allow list: if request.query.limit <= 10;
निम्नलिखित नियम सेट प्रदर्शित करता है कि प्रश्नों पर लगाए गए अवरोधों का मूल्यांकन करने वाले सुरक्षा नियमों को कैसे लिखा जाए। यह उदाहरण निम्न परिवर्तनों के साथ पिछली stories
नियमसेट का विस्तार करता है:
- नियम सेट पढ़ने के नियम को
get
औरlist
नियमों में अलग करता है। -
get
नियम एकल दस्तावेज़ों की पुनर्प्राप्ति को सार्वजनिक दस्तावेज़ों या उपयोगकर्ता द्वारा लिखे गए दस्तावेज़ों तक सीमित करता है। -
list
नियम वही प्रतिबंध लागू करता है जोget
लेकिन प्रश्नों के लिए। यह क्वेरी सीमा की भी जाँच करता है, फिर किसी सीमा के बिना या 10 से अधिक की सीमा के साथ किसी भी क्वेरी को अस्वीकार करता है। - कोड दोहराव से बचने के लिए नियमसेट
authorOrPublished()
फ़ंक्शन को परिभाषित करता है।
service cloud.firestore {
match /databases/{database}/documents {
match /stories/{storyid} {
// Returns `true` if the requested story is 'published'
// or the user authored the story
function authorOrPublished() {
return resource.data.published == true || request.auth.uid == resource.data.author;
}
// Deny any query not limited to 10 or fewer documents
// Anyone can query published stories
// Authors can query their unpublished stories
allow list: if request.query.limit <= 10 &&
authorOrPublished();
// Anyone can retrieve a published story
// Only a story's author can retrieve an unpublished story
allow get: if authorOrPublished();
// Only a story's author can write to a story
allow write: if request.auth.uid == resource.data.author;
}
}
}
संग्रह समूह प्रश्न और सुरक्षा नियम
डिफ़ॉल्ट रूप से, प्रश्नों को एक संग्रह के दायरे में रखा जाता है और वे केवल उस संग्रह से परिणाम प्राप्त करते हैं। संग्रह समूह प्रश्नों के साथ, आप एक ही आईडी वाले सभी संग्रहों वाले संग्रह समूह से परिणाम प्राप्त कर सकते हैं। यह खंड वर्णन करता है कि सुरक्षा नियमों का उपयोग करके अपने संग्रह समूह प्रश्नों को कैसे सुरक्षित किया जाए।
संग्रह समूहों के आधार पर सुरक्षित और क्वेरी दस्तावेज़
अपने सुरक्षा नियमों में, आपको संग्रह समूह के लिए नियम लिखकर संग्रह समूह प्रश्नों को स्पष्ट रूप से अनुमति देनी चाहिए:
- सुनिश्चित करें कि
rules_version = '2';
आपके नियम-सेट की पहली पंक्ति है। संग्रह समूह प्रश्नों के लिए सुरक्षा नियम संस्करण 2 के नए पुनरावर्ती वाइल्डकार्ड{name=**}
व्यवहार की आवश्यकता होती है। -
match /{path=**}/ [COLLECTION_ID] /{doc}
उपयोग करके अपने संग्रह समूह के लिए एक नियम लिखें।
उदाहरण के लिए, posts
उप-संग्रह वाले forum
दस्तावेज़ों में संगठित फ़ोरम पर विचार करें:
/मंचों/{मंचों}/पोस्टों/{postid}
{
author: "some_auth_id",
authorname: "some_username",
content: "I just read a great story.",
}
इस एप्लिकेशन में, हम पोस्ट को उनके स्वामियों द्वारा संपादन योग्य और प्रमाणित उपयोगकर्ताओं द्वारा पठनीय बनाते हैं:
service cloud.firestore {
match /databases/{database}/documents {
match /forums/{forumid}/posts/{post} {
// Only authenticated users can read
allow read: if request.auth != null;
// Only the post author can write
allow write: if request.auth != null && request.auth.uid == resource.data.author;
}
}
}
कोई भी प्रमाणीकृत उपयोगकर्ता किसी एक मंच के पदों को पुनः प्राप्त कर सकता है:
db.collection("forums/technology/posts").get()
लेकिन क्या होगा यदि आप वर्तमान उपयोगकर्ता को सभी मंचों पर उनकी पोस्ट दिखाना चाहते हैं? आप सभी posts
संग्रहों से परिणाम पुनर्प्राप्त करने के लिए संग्रह समूह क्वेरी का उपयोग कर सकते हैं:
var user = firebase.auth().currentUser;
db.collectionGroup("posts").where("author", "==", user.uid).get()
अपने सुरक्षा नियमों में, आपको posts
संग्रह समूह के लिए पठन या सूची नियम लिखकर इस क्वेरी को अनुमति देनी चाहिए:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Authenticated users can query the posts collection group
// Applies to collection queries, collection group queries, and
// single document retrievals
match /{path=**}/posts/{post} {
allow read: if request.auth != null;
}
match /forums/{forumid}/posts/{postid} {
// Only a post's author can write to a post
allow write: if request.auth != null && request.auth.uid == resource.data.author;
}
}
}
हालांकि, ध्यान दें कि ये नियम पदानुक्रम पर ध्यान दिए बिना, आईडी posts
वाले सभी संग्रहों पर लागू होंगे. उदाहरण के लिए, ये नियम निम्नलिखित सभी posts
संग्रहों पर लागू होते हैं:
-
/posts/{postid}
-
/forums/{forumid}/posts/{postid}
-
/forums/{forumid}/subforum/{subforumid}/posts/{postid}
एक क्षेत्र के आधार पर सुरक्षित संग्रह समूह प्रश्न
एकल-संग्रह प्रश्नों की तरह, संग्रह समूह प्रश्नों को भी आपके सुरक्षा नियमों द्वारा निर्धारित बाधाओं को पूरा करना चाहिए। उदाहरण के लिए, हम प्रत्येक फ़ोरम पोस्ट में एक published
फ़ील्ड जोड़ सकते हैं जैसे हमने उपरोक्त stories
उदाहरण में किया था:
/मंचों/{मंचों}/पोस्टों/{postid}
{
author: "some_auth_id",
authorname: "some_username",
content: "I just read a great story.",
published: false
}
फिर हम published
स्थिति और पोस्ट author
आधार पर posts
संग्रह समूह के लिए नियम लिख सकते हैं:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Returns `true` if the requested post is 'published'
// or the user authored the post
function authorOrPublished() {
return resource.data.published == true || request.auth.uid == resource.data.author;
}
match /{path=**}/posts/{post} {
// Anyone can query published posts
// Authors can query their unpublished posts
allow list: if authorOrPublished();
// Anyone can retrieve a published post
// Authors can retrieve an unpublished post
allow get: if authorOrPublished();
}
match /forums/{forumid}/posts/{postid} {
// Only a post's author can write to a post
allow write: if request.auth.uid == resource.data.author;
}
}
}
इन नियमों के साथ, वेब, ऐप्पल और एंड्रॉइड क्लाइंट निम्नलिखित प्रश्न कर सकते हैं:
कोई भी फ़ोरम में प्रकाशित पोस्ट पुनर्प्राप्त कर सकता है:
db.collection("forums/technology/posts").where('published', '==', true).get()
सभी मंचों पर कोई भी लेखक की प्रकाशित पोस्ट को पुनः प्राप्त कर सकता है:
db.collectionGroup("posts").where("author", "==", "some_auth_id").where('published', '==', true).get()
लेखक सभी मंचों पर अपने सभी प्रकाशित और अप्रकाशित पदों को पुनः प्राप्त कर सकते हैं:
var user = firebase.auth().currentUser; db.collectionGroup("posts").where("author", "==", user.uid).get()
संग्रह समूह और दस्तावेज़ पथ के आधार पर सुरक्षित और क्वेरी दस्तावेज़
कुछ मामलों में, आप दस्तावेज़ पथ के आधार पर संग्रह समूह प्रश्नों को प्रतिबंधित करना चाह सकते हैं। इन प्रतिबंधों को बनाने के लिए, आप फ़ील्ड के आधार पर दस्तावेज़ों को सुरक्षित करने और पूछताछ करने के लिए समान तकनीकों का उपयोग कर सकते हैं।
एक ऐसे एप्लिकेशन पर विचार करें जो कई स्टॉक और क्रिप्टोक्यूरेंसी एक्सचेंजों के बीच प्रत्येक उपयोगकर्ता के लेनदेन का ट्रैक रखता है:
/उपयोगकर्ता/{उपयोगकर्ता आईडी}/एक्सचेंज/{एक्सचेंजआईडी}/लेन-देन/{लेन-देन}
{
amount: 100,
exchange: 'some_exchange_name',
timestamp: April 1, 2019 at 12:00:00 PM UTC-7,
user: "some_auth_id",
}
user
क्षेत्र पर ध्यान दें। भले ही हम जानते हैं कि दस्तावेज़ के पथ से कौन सा उपयोगकर्ता transaction
दस्तावेज़ का मालिक है, हम प्रत्येक transaction
दस्तावेज़ में इस जानकारी की नकल करते हैं क्योंकि यह हमें दो काम करने की अनुमति देता है:
संग्रह समूह प्रश्न लिखें जो उन दस्तावेज़ों तक सीमित हैं जिनमें उनके दस्तावेज़ पथ में एक विशिष्ट
/users/{userid}
शामिल है। उदाहरण के लिए:var user = firebase.auth().currentUser; // Return current user's last five transactions across all exchanges db.collectionGroup("transactions").where("user", "==", user).orderBy('timestamp').limit(5)
transactions
संग्रह समूह पर सभी प्रश्नों के लिए इस प्रतिबंध को लागू करें ताकि एक उपयोगकर्ता दूसरे उपयोगकर्ता केtransaction
दस्तावेज़ों को पुनः प्राप्त नहीं कर सके।
हम इस प्रतिबंध को अपने सुरक्षा नियमों में लागू करते हैं और user
क्षेत्र के लिए डेटा सत्यापन शामिल करते हैं:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{path=**}/transactions/{transaction} {
// Authenticated users can retrieve only their own transactions
allow read: if resource.data.user == request.auth.uid;
}
match /users/{userid}/exchange/{exchangeid}/transactions/{transaction} {
// Authenticated users can write to their own transactions subcollections
// Writes must populate the user field with the correct auth id
allow write: if userid == request.auth.uid && request.data.user == request.auth.uid
}
}
}
अगले कदम
- भूमिका-आधारित अभिगम नियंत्रण के अधिक विस्तृत उदाहरण के लिए, उपयोगकर्ताओं और समूहों के लिए सुरक्षित डेटा पहुँच देखें।
- सुरक्षा नियम संदर्भ पढ़ें।