खास फ़ील्ड का ऐक्सेस कंट्रोल करना

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

कभी-कभी ऐसा भी हो सकता है कि आप किसी ऐसे दस्तावेज़ के परिवर्तनों को नियंत्रित करना चाहें, जो दस्तावेज़ स्तर पर लेकिन फ़ील्ड स्तर पर.

उदाहरण के लिए, हो सकता है कि आप क्लाइंट को एक दस्तावेज़ बनाने या बदलने की अनुमति देना चाहें, लेकिन उन्हें उस दस्तावेज़ के कुछ फ़ील्ड में बदलाव करने की अनुमति न दें. या हो सकता है कि आप लागू करें कि क्लाइंट के बनाए गए किसी भी दस्तावेज़ में फ़ील्ड. इस गाइड में बताया गया है कि Cloud Firestore के सुरक्षा नियम.

चुनिंदा फ़ील्ड के लिए, रीड ओनली ऐक्सेस देना

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

अगर दस्तावेज़ में ��ुछ ऐसे फ़ील्ड हैं जिन्हें आपको छिपाना है तो सबसे अच्छा तरीका यह होगा कि उन्हें एक अलग दस्तावेज़ में रखा जाए. इसके लिए उदाहरण के लिए, private सबकलेक्शन में दस्तावेज़ बनाने के बारे में सोचें पसंद:

/कर्मचारी/{emp_id}

  name: "Alice Hamilton",
  department: 461,
  start_date: <timestamp>

/कर्मचारी/{emp_id}/निजी/वित्त

    salary: 80000,
    bonus_mult: 1.25,
    perf_review: 4.2

इसके बाद, आपके पास ऐसे सुरक्षा नियम जोड़ने का विकल्प होता है जिनके पास अलग-अलग लेवल के ऐक्सेस हों दो संग्रह. इस उदाहरण में, हम पुष्टि के लिए कस्टम दावों का इस्तेमाल कर रहे हैं यह बताने के लिए कि सिर्फ़ Finance के बराबर कस्टम पुष्टि करने का दावा role करने वाले लोग कर सकते हैं किसी कर्मचारी की वित्तीय जानकारी देखते हैं.

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow any logged in user to view the public employee data
    match /employees/{emp_id} {
      allow read: if request.resource.auth != null
      // Allow only users with the custom auth claim of "Finance" to view
      // the employee's financial data
      match /private/finances {
        allow read: if request.resource.auth &&
          request.resource.auth.token.role == 'Finance'
      }
    }
  }
}

दस्तावेज़ बनाने में फ़ील्ड को सीमित करना

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

आप इसकी keys विधि की जांच करके ये नियम बना सकते हैं: request.resource.data ऑब्जेक्ट है. यह उन सभी फ़ील्ड की सूची है जिन्हें क्लाइंट इस नए दस्तावेज़ में लिखने का प्रयास कर रहा है. फ़ील्ड के इस सेट को जोड़कर hasOnly() जैसे फ़ंक्शन के साथ या hasAny(), में ऐसा लॉजिक जोड़ा जा सकता है जिससे यह तय होता है कि उपयोगकर्ता किस तरह के दस्तावेज़ों में जोड़ सकता है Cloud Firestore.

नए दस्तावेज़ों में खास फ़ील्ड की ज़रूरत

मान लें कि आपको यह पक्का करना है कि restaurant में बनाए गए सभी दस्तावेज़ संग्रह में कम से कम एक name, location, और city फ़ील्ड है. आप hasAll() पर कॉल करके ऐसा करें क्लिक करें.

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow the user to create a document only if that document contains a name
    // location, and city field
    match /restaurant/{restId} {
      allow create: if request.resource.data.keys().hasAll(['name', 'location', 'city']);
    }
  }
}

इससे दूसरे फ़ील्ड के साथ भी रेस्टोरेंट बनाए जा सकते हैं, लेकिन यह पक्का होता है कि यह कि क्लाइंट के बनाए गए सभी दस्तावेज़ों में कम से कम ये तीन फ़ील्ड हों.

नए दस्तावेज़ों में खास फ़ील्ड पर पाबंदी लगाना

इसी तरह, आप क्लाइंट को ऐसे दस्तावेज़ बनाने से रोक सकते हैं, जिनमें hasAny() का इस्तेमाल करके खास फ़ील्ड में जानकारी डालें प्रतिबंधित फ़ील्ड की सूची के साथ. यह तरीका 'सही' के तौर पर तब दिखता है, जब दस्तावेज़ में इनमें से कोई भी फ़ील्ड शामिल है, इसलिए हो सकता है कि आप का इस्तेमाल किया जा सकता है.

उदाहरण के लिए, नीचे दिए गए उदाहरण में, क्लाइंट को इस दस्तावेज़ में, average_score या rating_count फ़ील्ड शामिल है फ़ील्ड को बाद में सर्वर कॉल से जोड़ा जाएगा.

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow the user to create a document only if that document does *not*
    // contain an average_score or rating_count field.
    match /restaurant/{restId} {
      allow create: if (!request.resource.data.keys().hasAny(
        ['average_score', 'rating_count']));
    }
  }
}

नए दस्तावेज़ों के लिए, अनुमति वाले फ़ील्ड की सूची बनाना

नए दस्तावेज़ों में कुछ फ़ील्ड पर पाबंदी लगाने के बजाय, हो सकता है कि आप सिर्फ़ उन फ़ील्ड की सूची होगी जिनकी नए दस्तावेज़ों में साफ़ तौर पर अनुमति है. इसके बाद आप hasOnly() का इस्तेमाल कर सकते हैं फ़ंक्शन का उपयोग करके स��निश्चित करें कि बनाए गए किसी भी नए दस्तावेज़ में केवल ये फ़ील्ड शामिल हैं (या इन फ़ील्ड का एक सबसेट) और कोई दूसरा नहीं.

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow the user to create a document only if that document doesn't contain
    // any fields besides the ones listed below.
    match /restaurant/{restId} {
      allow create: if (request.resource.data.keys().hasOnly(
        ['name', 'location', 'city', 'address', 'hours', 'cuisine']));
    }
  }
}

ज़रूरी और वैकल्पिक फ़ील्ड को जोड़ना

अपनी सुरक्षा में, hasAll और hasOnly कार्रवाइयों को एक साथ जोड़ा जा सकता है नियमों के लिए कुछ फ़ील्ड का होना ज़रूरी है और कुछ को अनुमति देनी है. उदाहरण के लिए, यह उदाहरण सभी नए दस्तावेज़ों में name, location, और city शामिल होने चाहिए फ़ील्ड का इस्तेमाल किया जा सकता है. साथ ही, address, hours, और cuisine फ़ील्ड का इस्तेमाल किया जा सकता है.

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow the user to create a document only if that document has a name,
    // location, and city field, and optionally address, hours, or cuisine field
    match /restaurant/{restId} {
      allow create: if (request.resource.data.keys().hasAll(['name', 'location', 'city'])) &&
       (request.resource.data.keys().hasOnly(
           ['name', 'location', 'city', 'address', 'hours', 'cuisine']));
    }
  }
}

असल दुनिया की स्थिति में, इस लॉजिक को हेल्पर फ़ंक्शन में इस्तेमाल किया जा सकता है आपके कोड का दोहराव से बचने और वैकल्पिक कोड को ज़्यादा आसानी से जोड़ने के लिए किसी एक सूची में ज़रूरी फ़ील्ड जोड़ें, जैसे:

service cloud.firestore {
  match /databases/{database}/documents {
    function verifyFields(required, optional) {
      let allAllowedFields = required.concat(optional);
      return request.resource.data.keys().hasAll(required) &&
        request.resource.data.keys().hasOnly(allAllowedFields);
    }
    match /restaurant/{restId} {
      allow create: if verifyFields(['name', 'location', 'city'],
        ['address', 'hours', 'cuisine']);
    }
  }
}

अपडेट किए जाने वाले फ़ील्ड सीमित करना

सुरक्षा का एक सामान्य तरीका क्लाइंट को सिर्फ़ कुछ फ़ील्ड में बदलाव करने की अनुमति देना है अन्य. ऐसा करने के लिए आपको सिर्फ़ यह जानकारी नहीं मिलेगी कि request.resource.data.keys() सूची के बारे में पिछले सेक्शन में बताया गया है. इसकी वजह यह है सूची पूरे दस्तावेज़ को दिखाती है. यह बदलाव के बाद दिखाई जाती है और इसलिए, इसमें वे फ़ील्ड शामिल होंगे जिनमें क्लाइंट ने बदलाव नहीं किया है.

हालांकि, अगर diff() का इस्तेमाल किया जाता फ़ंक्शन है, तो आप request.resource.data की तुलना resource.data ऑब्जेक्ट, जो डेटाबेस में पहले से मौजूद दस्तावेज़ को दिखाता है अपडेट करने के लिए कहें. इससे एक mapDiff ऑब्जेक्ट, यानी वह ऑब्जेक्ट जिसमें दो अ��ग-अलग चीज़ों के बीच होने वाले सभी बदलाव शामिल होते हैं मैप.

affectedKeys() पर कॉल करके तरीका है, तो आपको फ़ील्ड का वे सेट दिख सकता है जिसमें बदलाव किए गए हैं बदलाव करें. इसके बाद, इन फ़ंक्शन का इस्तेमाल किया जा सकता है hasOnly() या hasAny() ताकि यह पक्का किया जा सके कि इस सेट में कुछ आइटम हैं या नहीं हैं.

कुछ फ़ील्ड को बदलने से रोकना

hasAny() का इस्तेमाल करके सेट पर दिया गया तरीका affectedKeys() से जनरेट हुआ है और नतीजे को नकारते हुए, आप क्लाइंट के ऐसे किसी भी अनुरोध को अस्वीकार कर सकते है जो उन फ़ील्ड को बदलें जिन्हें आप नहीं बदलना चाहते.

उदाहरण के लिए, हो सकता है कि आप क्लाइंट को लेकिन उनके औसत स्कोर या समीक्षाओं की संख्या में बदलाव नहीं करते.

service cloud.firestore {
  match /databases/{database}/documents {
    match /restaurant/{restId} {
      // Allow the client to update a document only if that document doesn't
      // change the average_score or rating_count fields
      allow update: if (!request.resource.data.diff(resource.data).affectedKeys()
        .hasAny(['average_score', 'rating_count']));
    }
  }
}

सिर्फ़ कुछ फ़ील्ड में बदलाव करने की अनुमति देना

जिन फ़ील्ड को आप नहीं बदलना चाहते उन्हें निर्दिष्ट करने के बजाय, आप hasOnly() फ़ंक्शन का इस्तेमाल करें. आम तौर पर, ऐसा होता है ज़्यादा सुरक्षित माना जाता है, क्योंकि किसी भी नए दस्तावेज़ फ़ील्ड में लिखने पर डिफ़ॉल्ट रूप से अस्वीकार किया जाता है, जब तक कि आप अपने सुरक्षा नियमों में इन्हें साफ़ तौर पर अनुमति नहीं देते.

उदाहरण के लिए, average_score और rating_count को अनुमति न देने के बजाय फ़ील्ड में, आप सुरक्षा नियम बना सकते हैं, जिससे क्लाइंट सिर्फ़ name, location, city, address, hours, और cuisine फ़ील्ड.

service cloud.firestore {
  match /databases/{database}/documents {
    match /restaurant/{restId} {
    // Allow a client to update only these 6 fields in a document
      allow update: if (request.resource.data.diff(resource.data).affectedKeys()
        .hasOnly(['name', 'location', 'city', 'address', 'hours', 'cuisine']));
    }
  }
}

इसका मतलब है कि अगर आने वाले समय में आपके ऐप्लिकेशन में रेस्टोरेंट के दस्तावेज़ बनाए जाएंगे, telephone फ़ील्ड शामिल करें, तो उस फ़ील्ड में बदलाव करने की कोशिश नहीं की जा सकेगी जब तक कि आप वापस जाकर उस फ़ील्ड को अपनी सुरक्षा में मौजूद hasOnly() सूची में न जोड़ लें नियम.

फ़ील्ड टाइप लागू किए जा रहे हैं

Cloud Firestore के स्कीमालेस होने का एक और असर यह होता है कि इसमें किस तरह के डेटा को सेव किया जा सकता है, इसके लिए डेटाबेस लेवल पर नीति उल्लंघन ठीक करने का तरीका (एनफ़ोर्समेंट) फ़िल्टर करें. इसे सुरक्षा के नियमों में लागू किया जा सकता है. हालांकि, is ऑपरेटर के साथ.

उदाहरण के लिए, यहां दिया गया सुरक्षा का नियम लागू होता है कि समीक्षा की score फ़ील्ड में कोई पूर्णांक, headline, content, और author_name फ़ील्ड होने चाहिए स्ट्रिंग हैं और review_date एक टाइमस्टैंप है.

service cloud.firestore {
  match /databases/{database}/documents {
    match /restaurant/{restId} {
      // Restaurant rules go here...
      match /review/{reviewId} {
        allow create: if (request.resource.data.score is int &&
          request.resource.data.headline is string &&
          request.resource.data.content is string &&
          request.resource.data.author_name is string &&
          request.resource.data.review_date is timestamp
        );
      }
    }
  }
}

is ऑपरेटर के लिए मान्य डेटा टाइप bool, bytes, float, int, और हैं list, latlng, number, path, map, string, और timestamp. is ऑपरेटर constraint, duration, set, और map_diff डेटा के साथ भी काम करता है किसी भी टाइप का इस्तेमाल कर सकते हैं. हालांकि, इन्हें सुरक्षा के नियमों की भाषा के ज़रिए जनरेट किया जाता है और यह क्लाइंट की ओर से जनरेट नहीं किया जाता है. साथ ही, मुमकिन है कि आप इसका इस्तेमाल सबसे सटीक परफ़ॉर्मेंस का इस्तेमाल करें.

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

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

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

service cloud.firestore {
  match /databases/{database}/documents {
  match /orders/{orderId} {
    allow create: if request.resource.data.tags is list &&
      request.resource.data.tags[0] is string &&
      request.resource.data.product is map &&
      request.resource.data.product.name is string &&
      request.resource.data.product.quantity is int
      }
    }
  }
}

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

service cloud.firestore {
  match /databases/{database}/documents {

  function reviewFieldsAreValidTypes(docData) {
     return docData.score is int &&
          docData.headline is string &&
          docData.content is string &&
          docData.author_name is string &&
          docData.review_date is timestamp;
  }

   match /restaurant/{restId} {
      // Restaurant rules go here...
      match /review/{reviewId} {
        allow create: if reviewFieldsAreValidTypes(request.resource.data) &&
          // Other rules may go here
        allow update: if reviewFieldsAreValidTypes(request.resource.data) &&
          // Other rules may go here
      }
    }
  }
}

वैकल्पिक फ़ील्ड के लिए टाइप लागू करना

यह याद रखना ज़रूरी है कि request.resource.data.foo को कॉल करने के दौरान वह दस्तावेज़ जिसमें foo मौजूद नहीं होने पर गड़बड़ी होती है. इसी वजह से कोई गड़बड़ी होती है सुरक्षा नियम के मुताबिक कॉल करने पर, यह अनुरोध अस्वीकार कर दिया जाएगा. इसे ठीक किया जा सकता है get का इस्तेमाल करके समस्या को हल करें request.resource.data पर तरीका. get तरीके का इस्तेमाल करके, जिस फ़ील्ड को मैप से वापस लाया जा रहा है उसके लिए डिफ़ॉल्ट आर्ग्युमेंट, अगर वह फ़ील्ड मौजूद नहीं है.

उदाहरण के लिए, अगर समीक्षा वाले दस्तावेज़ों में एक वैकल्पिक photo_url फ़ील्ड भी शामिल हो साथ ही, स्ट्रिंग और सूचियां होने की पुष्टि करने ���े लिए, एक tags फ़ील्ड भी है. हालांकि, ऐसा करना ज़रूरी नहीं है तो आप reviewFieldsAreValidTypes फ़ंक्शन को कुछ ऐसा करता है:

  function reviewFieldsAreValidTypes(docData) {
     return docData.score is int &&
          docData.headline is string &&
          docData.content is string &&
          docData.author_name is string &&
          docData.review_date is timestamp &&
          docData.get('photo_url', '') is string &&
          docData.get('tags', []) is list;
  }

इससे वे दस्तावेज़ अस्वीकार कर दिए जाते हैं जिनमें tags मौजूद होता है. हालांकि, यह सूची नहीं है ऐसे दस्तावेज़ों की अनुमति देना जिनमें tags (या photo_url) फ़ील्ड शामिल न हो.

आंशिक रूप से लिखने की अनुमति नहीं है

Cloud Firestore के सुरक्��ा नियमों के बारे में एक आखिरी बात यह है कि इनमें क्लाइंट का उपयोग कर सकते हैं या वे पूरे संपादन को अस्वीकार कर देते हैं. आप ऐसे सुरक्षा नियम नहीं बना सकते जो आपके फ़ील्ड में कुछ फ़ील्ड में लिखना स्वीकार करते हों दस्तावेज़ में कॉपी करने के लिए सबमिट करें.