डेटा को सुरक्षित तरीके से क्वेरी करें

इस पेज पर, इन विषयों के बारे में जानकारी दी गई है सुरक्षा नियमों का स्ट्रक्चर बनाना और सुरक्षा नियमों के लिए लिखने की शर्तें, ताकि यह बताया जा सके कि Cloud Firestore के सुरक्षा नियम, क्वेरी के साथ इंटरैक्ट करते हैं. यह इस बात पर बारीकी से नज़र रखता है कि सुरक्षा नियम उन क्वेरी पर असर डालते हैं जिन्हें लिखा जा सकता है. साथ ही, यह भी बताया गया है कि क् वेरी, आपके सुरक्षा नियमों के समान प्रतिबंधों का उपयोग करती हैं. इस पेज पर भी बताता है कि क्वेरी के आधार पर क्वेरी को अनुमति देने या अस्वीकार करने के लिए, सुरक्षा नियम कैसे लिखें limit और orderBy जैसी प्रॉपर्टी.

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

दस्तावेज़ों को वापस पाने के लिए क्वेरी लिखते समय, ध्यान रखें कि सुरक्षा के नियम फ़िल्टर नहीं हैं—क्वेरी पूरी तरह से हैं या कुछ नहीं. आपका समय और संसाधन बचाने के लिए, Cloud Firestore, संभावित नतीजों के सेट के आधार पर क्वेरी का आकलन करता है का इस्तेमाल करें. अगर कोई क्वेरी संभावित तौर पर ऐसे दस्तावेज़ दिखाए जाते हैं जिन्हें पढ़ने की क्लाइंट अनुमति नहीं देता, पूरा अनुरोध पूरा नहीं किया जा सकता.

क्वेरी और सुरक्षा के नियम

जैसा कि नीचे दिए गए उदाहरण में बताया गया है, आपको क्वेरी को इस तरह लिखें कि वह की सीमाएं भी तय करें.

auth.uid पर आधारित दस्तावेज़ सुरक्षित और क्वेरी करें

यहां दिए गए उदाहरण में, दस्तावेज़ों को वापस पाने के लिए क्वेरी लिखने का तरीका बताया गया है किसी सुरक्षा नियम से सुरक्षित किया जाता है. उस डेटाबेस पर विचार करें जिसमें story दस्तावेज़:

/stories/{storyid}

{
  title: "A Great Story",
  content: "Once upon a time...",
  author: "some_auth_id",
  published: false
}

title और content फ़ील्ड के अलावा, हर दस्तावेज़ में ऐक्सेस कंट्रोल के लिए, author और published फ़ील्ड. ये उदाहरण author फ़ील्ड सेट करने के लिए ऐप्लिकेशन, Firebase से पुष्टि करने की सुविधा का इस्तेमाल करता है उपयोगकर्ता के यूआईडी के लिए सबमिट किया जाता है. Firebase पुष्टि करने से, request.auth वैरिएबल में भी जानकारी अपने-आप भर जाती है के बारे में जानते हैं.

नीचे दिया गया सुरक्षा नियम request.auth और हर resource.data वैरिएबल के लिए, पढ़ने और लिखने का ऐक्सेस रोकना story को इसके लेखक के लिए:

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 दस्तावेज़. इस व्यवहार की वजह यह है कि Cloud Firestore आपके सुरक्षा के नियमों को लागू करता है और क्वेरी का आकलन करता है इसके संभावित नतीजे के सेट के मुताबिक नहीं, बल्कि इसकी असल प्रॉपर्टी के ख़िलाफ़ होता है आपके डेटाबेस के दस्तावेज़. क्या किसी क्वेरी में संभावित रूप से दस्तावेज़ शामिल हो सकते हैं जो आपके सुरक्षा नियमों का उल्लंघन करती हैं, तो क्वेरी फ़ेल हो जाएगी.

इसके उलट, नीचे दी गई क्वेरी सफल होती है, क्योंकि इसमें वही जानकारी शामिल है कंस्ट्रेंट को 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;
    }

  }
}

कलेक्शन ग्रुप की क्वेरी और सुरक्षा के नियम

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

कलेक्शन ग्रुप के आधार पर, सुरक्षित और क्वेरी वाले दस्तावेज़

अपने सुरक्षा नियमों में, आपको साफ़ तौर पर इसकी अनुमति देनी होगी कलेक्शन ग्रुप की क्वेरी करने के लिए:

  1. पक्का करें कि आपके नियमों-सेट की पहली लाइन rules_version = '2'; है. डेटा इकट्ठा करना ग्रुप क्वेरी के लिए सुरक्षा का नया रिकर्सिव वाइल्डकार्ड {name=**} व्यवहार नियम वर्शन 2.
  2. इसका इस्तेमाल करके अपने संग्रह समूह के लिए एक नियम लिखें match /{path=**}/[COLLECTION_ID]/{doc}.

उदाहरण के लिए, ऐसे forum दस्तावेज़ों में व्यवस्थित किए गए फ़ोरम पर विचार करें जिनमें ये शामिल हों posts उप-संग्रह:

/फ़ोरम/{forumid}/पोस्ट/{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 के उदाहरण में किया था:

/फ़ोरम/{forumid}/पोस्ट/{postid}

{
  author: "some_auth_id",
  authorname: "some_username",
  content: "I just read a great story.",
  published: false
}

इसके बाद, हम posts कलेक्शन ग्रुप के लिए नियम बना सकते हैं. published स्थिति और पोस्ट author:

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

इन नियमों का इस्तेमाल करके वेब, Apple, और Android क्लाइंट ये क्वेरी कर सकते हैं:

  • कोई भी व्यक्ति किसी फ़ोरम में प्रकाशित पोस्ट को फिर से पा सकता है:

    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()
    

कलेक्शन ग्रुप और दस्तावेज़ के पाथ के आधार पर, दस्तावेज़ों को सुरक्षित और क्वेरी करें

कुछ मामलों में, कलेक्शन ग्रुप की क्वेरी को दस्तावेज़ का पाथ. इन पाबंदियों को बनाने के लिए, समान तकनीकों का इस्तेमाल फ़ील्ड के आधार पर दस्तावेज़ों को सुरक्षित करना और क्वेरी करना.

ऐसे ऐप्लिकेशन पर विचार करें जो हर उपयोगकर्ता के लेन-देन पर नज़र रखता है शेयर और क्रिप्टो करंसी एक्सचेंज में:

/users/{userid}/exchange/{exchangeid}/transactions/{transaction}

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

अगले चरण