रीयलटाइम डेटाबेस सुरक्षा नियम भाषा के मूल सिंटैक्स को जानें

संग्रह की मदद से व्यवस्थित रहें अपनी प्राथमिकताओं के आधार पर, कॉन्टेंट को सेव करें और कैटगरी में बांटें.

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

रीयलटाइम डेटाबेस सुरक्षा नियम आपके डेटाबेस के लिए घोषणात्मक कॉन्फ़िगरेशन हैं। इसका मतलब है कि नियमों को उत्पाद तर्क से अलग परिभाषित किया गया है। इसके कई फायदे हैं: ग्राहक सुरक्षा लागू करने के लिए ज़िम्मेदार नहीं हैं, बग्गी कार्यान्वयन आपके डेटा से समझौता नहीं करेगा, और शायद सबसे महत्वपूर्ण बात यह है कि दुनिया से डेटा की सुरक्षा के लिए सर्वर जैसे मध्यवर्ती रेफरी की कोई आवश्यकता नहीं है।

इस विषय में मूल सिंटैक्स और संरचना के बारे में बताया गया है, रीयलटाइम डेटाबेस सुरक्षा नियम, जिनका इस्तेमाल पूरे नियम सेट बनाने के लिए किया जाता है.

अपने सुरक्षा नियमों की संरचना करना

रीयलटाइम डेटाबेस सुरक्षा नियम JSON दस्तावेज़ में मौजूद JavaScript जैसी अभिव्यक्तियों से बने होते हैं। आपके नियमों की संरचना को आपके डेटाबेस में संग्रहीत डेटा की संरचना का पालन करना चाहिए।

बुनियादी नियम सुरक्षित किए जाने वाले नोड्स के एक सेट की पहचान करते हैं , एक्सेस के तरीके (जैसे, पढ़ना, लिखना) शामिल हैं, और ऐसी शर्तें जिनके तहत एक्सेस की अनुमति है या अस्वीकार है। निम्नलिखित उदाहरणों में, हमारी शर्तें सरल true और false कथन होंगी, लेकिन अगले विषय में हम शर्तों को व्यक्त करने के अधिक गतिशील तरीकों को शामिल करेंगे।

इसलिए, उदाहरण के लिए, यदि हम एक child_node को parent_node के तहत सुरक्षित करने का प्रयास कर रहे हैं, तो अनुसरण करने के लिए सामान्य सिंटैक्स है:

{
  "rules": {
    "parent_node": {
      "child_node": {
        ".read": <condition>,
        ".write": <condition>,
        ".validate": <condition>,
      }
    }
  }
}

आइए इस पैटर्न को लागू करें। उदाहरण के लिए, मान लें कि आप संदेशों की एक सूची का ट्रैक रख रहे हैं और आपके पास ऐसा डेटा है जो इस तरह दिखता है:

{
  "messages": {
    "message0": {
      "content": "Hello",
      "timestamp": 1405704370369
    },
    "message1": {
      "content": "Goodbye",
      "timestamp": 1405704395231
    },
    ...
  }
}

आपके नियमों को इसी तरह संरचित किया जाना चाहिए। यहां रीड-ओनली सुरक्षा के लिए नियमों का एक सेट दिया गया है जो इस डेटा संरचना के लिए उपयोगी हो सकता है। यह उदाहरण दिखाता है कि हम डेटाबेस नोड्स को कैसे निर्दिष्ट करते हैं जो नियम लागू होते हैं और उन नोड्स पर नियमों का मूल्यांकन करने की शर्तें।

{
  "rules": {
    // For requests to access the 'messages' node...
    "messages": {
      // ...and the individual wildcarded 'message' nodes beneath
      // (we'll cover wildcarding variables more a bit later)....
      "$message": {

        // For each message, allow a read operation if <condition>. In this
        // case, we specify our condition as "true", so read access is always granted.
        ".read": "true",

        // For read-only behavior, we specify that for write operations, our
        // condition is false.
        ".write": "false"
      }
    }
  }
}

बुनियादी नियम संचालन

डेटा पर किए जा रहे ऑपरेशन के प्रकार के आधार पर सुरक्षा लागू करने के लिए तीन प्रकार के नियम हैं: .write , .read , और .validate । यहाँ उनके उद्देश्यों का एक त्वरित सारांश है:

नियम प्रकार
।पढ़ना वर्णन करता है कि क्या और कब डेटा को उपयोगकर्ताओं द्वारा पढ़ने की अनुमति है।
।लिखो वर्णन करता है कि क्या और कब डेटा को लिखने की अनुमति है।
मान्य करें परिभाषित करता है कि एक सही ढंग से स्वरूपित मान कैसा दिखेगा, चाहे उसमें बाल विशेषताएँ हों, और डेटा प्रकार।

वाइल्डकार्ड कैप्चर चर

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

{
  "rules": {
    "rooms": {
      // this rule applies to any child of /rooms/, the key for each room id
      // is stored inside $room_id variable for reference
      "$room_id": {
        "topic": {
          // the room's topic can be changed if the room id has "public" in it
          ".write": "$room_id.contains('public')"
        }
      }
    }
  }
}

डायनेमिक $ वेरिएबल्स का उपयोग निरंतर पथ नामों के साथ समानांतर में भी किया जा सकता है। इस उदाहरण में, हम एक .validate नियम घोषित करने के लिए $other चर का उपयोग कर रहे हैं जो सुनिश्चित करता है कि widget में title और color के अलावा कोई सन्तान नहीं है। कोई भी ऐसा लेखन जिसके परिणामस्वरूप अतिरिक्त बच्चे पैदा होंगे, विफल हो जाएगा।

{
  "rules": {
    "widget": {
      // a widget can have a title or color attribute
      "title": { ".validate": true },
      "color": { ".validate": true },

      // but no other child paths are allowed
      // in this case, $other means any key excluding "title" and "color"
      "$other": { ".validate": false }
    }
  }
}

पढ़ें और लिखें नियम कैस्केड

.read और .write नियम ऊपर से नीचे तक काम करते हैं, गहरे नियमों पर हावी होने वाले उथले नियमों के साथ। यदि कोई नियम किसी विशेष पथ पर पढ़ने या लिखने की अनुमति देता है, तो वह इसके तहत सभी चाइल्ड नोड्स तक पहुंच भी प्रदान करता है। निम्नलिखित संरचना पर विचार करें:

{
  "rules": {
     "foo": {
        // allows read to /foo/*
        ".read": "data.child('baz').val() === true",
        "bar": {
          /* ignored, since read was allowed already */
          ".read": false
        }
     }
  }
}

यह सुरक्षा संरचना /bar/ को तब से पढ़ने की अनुमति देती है जब भी /foo/ में true मान वाला चाइल्ड baz होता है। ".read": false नियम /foo/bar/ के तहत यहां कोई प्रभाव नहीं पड़ता है, क्योंकि बाल पथ द्वारा पहुंच को रद्द नहीं किया जा सकता है।

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

ध्यान दें कि .validate नियम कैस्केड नहीं करते हैं। लिखने की अनुमति के लिए सभी वैध नियमों को पदानुक्रम के सभी स्तरों पर संतुष्ट होना चाहिए।

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

नियम परमाणु तरीके से लागू होते हैं। इसका अर्थ है कि यदि उस स्थान पर या पैरेंट स्थान पर पहुँच प्रदान करने वाला कोई नियम नहीं है, तो पठन या लेखन कार्रवाई तुरंत विफल हो जाती है. यहां तक ​​कि अगर हर प्रभावित चाइल्ड पाथ पहुंच योग्य है, पैरेंट स्थान पर पढ़ना पूरी तरह विफल हो जाएगा। इस संरचना पर विचार करें:

{
  "rules": {
    "records": {
      "rec1": {
        ".read": true
      },
      "rec2": {
        ".read": false
      }
    }
  }
}

यह समझे बिना कि नियमों का परमाणु रूप से मूल्यांकन किया जाता है, ऐसा लग सकता है कि /records/ पथ लाने से rec1 वापस आ जाएगा लेकिन rec2 नहीं। हालाँकि, वास्तविक परिणाम एक त्रुटि है:

जावास्क्रिप्ट
var db = firebase.database();
db.ref("records").once("value", function(snap) {
  // success method is not called
}, function(err) {
  // error callback triggered with PERMISSION_DENIED
});
उद्देश्य सी
नोट: यह फायरबेस उत्पाद ऐप क्लिप लक्ष्य पर उपलब्ध नहीं है।
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
[[_ref child:@"records"] observeSingleEventOfType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) {
  // success block is not called
} withCancelBlock:^(NSError * _Nonnull error) {
  // cancel block triggered with PERMISSION_DENIED
}];
तीव्र
नोट: यह फायरबेस उत्पाद ऐप क्लिप लक्ष्य पर उपलब्ध नहीं है।
var ref = FIRDatabase.database().reference()
ref.child("records").observeSingleEventOfType(.Value, withBlock: { snapshot in
    // success block is not called
}, withCancelBlock: { error in
    // cancel block triggered with PERMISSION_DENIED
})
जावा
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("records");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    // success method is not called
  }

  @Override
  public void onCancelled(FirebaseError firebaseError) {
    // error callback triggered with PERMISSION_DENIED
  });
});
आराम
curl https://docs-examples.firebaseio.com/rest/records/
# response returns a PERMISSION_DENIED error

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

जावास्क्रिप्ट
var db = firebase.database();
db.ref("records/rec1").once("value", function(snap) {
  // SUCCESS!
}, function(err) {
  // error callback is not called
});
उद्देश्य सी
नोट: यह फायरबेस उत्पाद ऐप क्लिप लक्ष्य पर उपलब्ध नहीं है।
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
[[ref child:@"records/rec1"] observeSingleEventOfType:FEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) {
    // SUCCESS!
}];
तीव्र
नोट: यह फायरबेस उत्पाद ऐप क्लिप लक्ष्य पर उपलब्ध नहीं है।
var ref = FIRDatabase.database().reference()
ref.child("records/rec1").observeSingleEventOfType(.Value, withBlock: { snapshot in
    // SUCCESS!
})
जावा
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("records/rec1");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    // SUCCESS!
  }

  @Override
  public void onCancelled(FirebaseError firebaseError) {
    // error callback is not called
  }
});
आराम
curl https://docs-examples.firebaseio.com/rest/records/rec1
# SUCCESS!

ओवरलैपिंग स्टेटमेंट्स

एक नोड पर एक से अधिक नियम लागू होना संभव है। ऐसे मामले में जहां कई नियम अभिव्यक्तियाँ एक नोड की पहचान करती हैं, यदि कोई भी स्थिति false है, तो पहुँच विधि को अस्वीकार कर दिया जाता है:

{
  "rules": {
    "messages": {
      // A rule expression that applies to all nodes in the 'messages' node
      "$message": {
        ".read": "true",
        ".write": "true"
      },
      // A second rule expression applying specifically to the 'message1` node
      "message1": {
        ".read": "false",
        ".write": "false"
      }
    }
  }
}

उपरोक्त उदाहरण में, संदेश 1 नोड को message1 जाता है क्योंकि दूसरा नियम हमेशा false होता है, भले ही पहला नियम हमेशा true

अगले कदम

आप फायरबेस रीयलटाइम डेटाबेस सुरक्षा नियमों की अपनी समझ को और बढ़ा सकते हैं:

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

  • विशिष्ट सुरक्षा उपयोग मामलों और उन्हें संबोधित करने वाले Firebase सुरक्षा नियमों की परिभाषाओं की समीक्षा करें।