सुरक्षा के नियम कैसे काम करते हैं

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

Firebase Security Rules मिडल (सर्वर) लेयर हटाएं और सीधे आपके डेटा से कनेक्ट करने वाले क्लाइंट के लिए, पाथ के आधार पर अनुमतियां तय करने की अनुमति दें. आने वाले अनुरोधों पर नियम कैसे लागू होते हैं, इस बारे में ज़्यादा जानने के लिए इस गाइड का इस्तेमाल करें.

किसी प्रॉडक्ट के नियमों के बारे में ज़्यादा जानने के लिए, वह प्रॉडक्ट चुनें.

Cloud Firestore

बुनियादी स्ट्रक्चर

Cloud Firestore और Cloud Storage में Firebase Security Rules के लिए, इस स्ट्रक्चर और सिंटैक्स का इस्तेमाल करें:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

नियम बनाते समय, इन ज़रूरी कॉन्सेप्ट को समझना ज़रूरी है:

  • अनुरोध: allow स्टेटमेंट में इस्तेमाल किया गया तरीका या तरीके. ये ऐसे तरीक़े हैं जिन्हें चलाने की अनुमति दी जा रही है. स्टैंडर्ड तरीके ये हैं: get, list, create, update, और delete. read और write के आसान तरीके, दिए गए डेटाबेस या स्टोरेज पाथ पर, पढ़ने और लिखने का ऐक्सेस देते हैं.
  • पाथ: डेटाबेस या स्टोरेज की जगह, जिसे यूआरआई पाथ के तौर पर दिखाया जाता है.
  • नियम: allow स्टेटमेंट, जिसमें एक शर्त शामिल होती है. अगर यह शर्त सही होती है, तो अनुरोध को अनुमति दी जाती है.

सुरक्षा के नियमों का दूसरा वर्शन

मई 2019 से, Firebase के सुरक्षा नियमों का दूसरा वर्शन उपलब्ध है. नियमों के दूसरे वर्शन में, बार-बार इस्तेमाल होने वाले वाइल्डकार्ड {name=**} के काम करने का तरीका बदला गया है. अगर आपको कलेक्शन ग्रुप क्वेरी का इस्तेमाल करना है, तो आपको वर्शन 2 का इस्तेमाल करना होगा. आपको अपने सुरक्षा नियमों में rules_version = '2'; को पहली पंक्ति बनाकर, वर्शन 2 के लिए ऑप्ट-इन करना होगा:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {

मिलते-जुलते पाथ

मैच करने वाले सभी स्टेटमेंट, दस्तावेज़ों पर ले जाने चाहिए, न कि कलेक्शन पर. मैच स्टेटमेंट, match /cities/SF की तरह किसी खास दस्तावेज़ पर ले जा सकता है या match /cities/{city} की तरह दिए गए पाथ में मौजूद किसी भी दस्तावेज़ पर ले जाने के लिए वाइल्डकार्ड का इस्तेमाल कर सकता है.

ऊपर दिए गए उदाहरण में, मैच स्टेटमेंट में {city} वाइल्डकार्ड सिंटैक्स का इस्तेमाल किया गया है. इसका मतलब है कि यह नियम cities कलेक्शन के किसी भी दस्तावेज़ पर लागू होता है, जैसे कि /cities/SF या /cities/NYC. जब मैच स्टेटमेंट में allow एक्सप्रेशन का आकलन किया जाता है, तो city वैरिएबल, शहर के दस्तावेज़ के नाम पर सेट हो जाएगा. जैसे, SF या NYC.

मिलते-जुलते सब-कलेक्शन

Cloud Firestore में डेटा को दस्तावेज़ों के कलेक्शन में व्यवस्थित किया जाता है. साथ ही, हर दस्तावेज़ में सब-कलेक्शन की मदद से हैरारकी को बढ़ाया जा सकता है. यह समझना ज़रूरी है कि सुरक्षा नियम, हैरारकी वाले डेटा के साथ कैसे इंटरैक्ट करते हैं.

मान लें कि cities कलेक्शन के हर दस्तावेज़ में एक landmarks सब-कलेक्शन है. सुरक्षा से जुड़े नियम सिर्फ़ मैच होने वाले पाथ पर लागू होते हैं. इसलिए, cities कलेक्शन पर तय किए गए ऐक्सेस कंट्रोल, landmarks सब-कलेक्शन पर लागू नहीं होते. इसके बजाय, सब-कलेक्शन का ऐक्सेस कंट्रोल करने के लिए साफ़ तौर पर नियम लिखें:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      allow read, write: if <condition>;

      // Explicitly define rules for the 'landmarks' subcollection
      match /landmarks/{landmark} {
        allow read, write: if <condition>;
      }
    }
  }
}

match स्टेटमेंट को नेस्ट करते समय, अंदरूनी match स्टेटमेंट का पाथ, हमेशा बाहरी match स्टेटमेंट के पाथ के हिसाब से होता है. इसलिए, ये नियमों के सेट एक जैसे हैं:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      match /landmarks/{landmark} {
        allow read, write: if <condition>;
      }
    }
  }
}
service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city}/landmarks/{landmark} {
      allow read, write: if <condition>;
    }
  }
}

बार-बार इस्तेमाल होने वाले वाइल्डकार्ड

अगर आपको किसी भी तरह की हैरारकी पर नियम लागू करने हैं, तो {name=**} के रीकर्सिव वाइल्डकार्ड सिंटैक्स का इस्तेमाल करें:

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

बार-बार इस्तेमाल होने वाले वाइल्डकार्ड सिंटैक्स का इस्तेमाल करने पर, वाइल्डकार्ड वैरिएबल में मैच होने वाला पूरा पाथ सेगमेंट शामिल होगा. भले ही, दस्तावेज़ किसी नेस्ट किए गए सबकलेक्शन में हो. उदाहरण के लिए, ऊपर दिए गए नियम, /cities/SF/landmarks/coit_tower में मौजूद दस्तावेज़ से मैच करेंगे. साथ ही, document वैरिएबल की वैल्यू SF/landmarks/coit_tower होगी.

हालांकि, ध्यान दें कि बार-बार इस्तेमाल होने वाले वाइल्डकार्ड का व्यवहार, नियमों के वर्शन पर निर्भर करता है.

वर्शन 1

सुरक्षा के नियम, डिफ़ॉल्ट रूप से वर्शन 1 का इस्तेमाल करते हैं. पहले वर्शन में, बार-बार इस्तेमाल होने वाले वाइल्डकार्ड, एक या एक से ज़्यादा पाथ आइटम से मैच करते हैं. ये खाली पाथ से मेल नहीं खाते. इसलिए, match /cities/{city}/{document=**}, सब-कलेक्शन में मौजूद दस्तावेज़ों से मेल खाता है, लेकिन cities कलेक्शन में मौजूद दस्तावेज़ों से नहीं. वहीं, match /cities/{document=**}, cities कलेक्शन और सब-कलेक्शन, दोनों में मौजूद दस्तावेज़ों से मेल खाता है.

बार-बार इस्तेमाल होने वाले वाइल्डकार्ड, मैच स्टेटमेंट के आखिर में होने चाहिए.

वर्शन 2

सुरक्षा नियमों के वर्शन 2 में, बार-बार इस्तेमाल होने वाले वाइल्डकार्ड, शून्य या एक से ज़्यादा पाथ आइटम से मैच करते हैं. match/cities/{city}/{document=**}, किसी भी सबकलेक्शन के साथ-साथ cities कलेक्शन के दस्तावेज़ों से मेल खाता है.

आपको अपने सुरक्षा नियमों में सबसे ऊपर rules_version = '2'; जोड़कर, वर्शन 2 में ऑप्ट-इन करना होगा:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{city}/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

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

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the songs collection group
    match /{path=**}/songs/{song} {
      allow read, write: if <condition>;
    }
  }
}

अगर कलेक्शन ग्रुप क्वेरी का इस्तेमाल किया जाता है, तो आपको कलेक्शन ग्रुप क्वेरी को सुरक्षित करना लेख में बताए गए वर्शन 2 का इस्तेमाल करना होगा.

ओवरलैप होने वाले मैच स्टेटमेंट

ऐसा हो सकता है कि कोई दस्तावेज़, एक से ज़्यादा match स्टेटमेंट से मैच करे. अगर एक से ज़्यादा allow एक्सप्रेशन किसी अनुरोध से मैच करते हैं, तो ऐक्सेस तब दिया जाता है, जब कोई भी शर्त true हो:

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the 'cities' collection.
    match /cities/{city} {
      allow read, write: if false;
    }

    // Matches any document in the 'cities' collection or subcollections.
    match /cities/{document=**} {
      allow read, write: if true;
    }
  }
}

ऊपर दिए गए उदाहरण में, cities कलेक्शन में सभी रीड और राइट की अनुमति होगी, क्योंकि दूसरा नियम हमेशा true होता है. भले ही, पहला नियम हमेशा false हो.

सुरक्षा नियम की सीमाएं

सुरक्षा नियमों के साथ काम करते समय, इन सीमाओं का ध्यान रखें:

सीमा विवरण
हर अनुरोध के लिए, exists(), get(), और getAfter() कॉल की ज़्यादा से ज़्यादा संख्या
  • एक दस्तावेज़ के अनुरोध और क्वेरी के अनुरोध के लिए 10.
  • एक से ज़्यादा दस्तावेज़ों को पढ़ने, लेन-देन, और एक साथ कई दस्तावेज़ों में डेटा लिखने के लिए 20. हर ऑपरेशन पर, 10 की पिछली सीमा भी लागू होती है.

    उदाहरण के लिए, मान लें कि आपने एक साथ कई डेटा डालने का अनुरोध किया है. इसमें तीन डेटा डालने के ऑपरेशन हैं और आपके सुरक्षा नियम, हर डेटा डालने की पुष्टि करने के लिए, दस्तावेज़ के दो ऐक्सेस कॉल का इस्तेमाल करते हैं. इस मामले में, हर बार लिखने के लिए, 10 में से दो ऐक्सेस कॉल का इस्तेमाल किया जाता है. साथ ही, एक साथ कई बार लिखने के अनुरोध के लिए, 20 में से छह ऐक्सेस कॉल का इस्तेमाल किया जाता है.

इनमें से किसी भी सीमा को पार करने पर, 'अनुमति नहीं दी गई' गड़बड़ी का मैसेज दिखता है.

दस्तावेज़ के ऐक्सेस के कुछ अनुरोध कैश मेमोरी में सेव किए जा सकते हैं. कैश मेमोरी में सेव किए गए अनुरोधों की गिनती, अनुरोधों की सीमा में नहीं की जाती.

नेस्ट किए गए match स्टेटमेंट की ज़्यादा से ज़्यादा गहराई 10
नेस्ट किए गए match स्टेटमेंट के सेट में, पाथ सेगमेंट में पाथ की ज़्यादा से ज़्यादा लंबाई 100
नेस्ट किए गए match स्टेटमेंट के सेट में, पाथ कैप्चर वैरिएबल की ज़्यादा से ज़्यादा संख्या 20
फ़ंक्शन कॉल की ज़्यादा से ज़्यादा गहराई 20
फ़ंक्शन के आर्ग्युमेंट की ज़्यादा से ज़्यादा संख्या 7
हर फ़ंक्शन के लिए let वैरिएबल बाइंडिंग की ज़्यादा से ज़्यादा संख्या 10
बार-बार या चक्रीय तौर पर फ़ंक्शन कॉल करने की ज़्यादा से ज़्यादा संख्या 0 &lpar;अनुमति नहीं है&rpar;
हर अनुरोध के लिए, एक्सप्रेशन की ज़्यादा से ज़्यादा संख्या 1,000
नियमों के सेट का ज़्यादा से ज़्यादा साइज़ नियमों के सेट का साइज़, इन दो सीमाओं के अंदर होना चाहिए:
  • Firebase कंसोल से पब्लिश किए गए या firebase deploy का इस्तेमाल करके सीएलआई से पब्लिश किए गए, नियमों के टेक्स्ट सोर्स के साइज़ पर 256 केबी की सीमा.
  • Firebase, सोर्स को प्रोसेस करके उसे बैक-एंड पर चालू करता है. इस प्रोसेस के दौरान, 250 केबी तक के नियमों का कंपाइल किया गया सेट बनाया जाता है.

Cloud Storage

बुनियादी स्ट्रक्चर

Cloud Firestore और Cloud Storage में Firebase Security Rules के लिए, इस स्ट्रक्चर और सिंटैक्स का इस्तेमाल करें:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

नियम बनाते समय, इन ज़रूरी कॉन्सेप्ट को समझना ज़रूरी है:

  • अनुरोध: allow स्टेटमेंट में इस्तेमाल किया गया तरीका या तरीके. ये ऐसे तरीक़े हैं जिन्हें चलाने की अनुमति दी जा रही है. स्टैंडर्ड तरीके ये हैं: get, list, create, update, और delete. read और write के आसान तरीके, दिए गए डेटाबेस या स्टोरेज पाथ पर, पढ़ने और लिखने का ऐक्सेस देते हैं.
  • पाथ: डेटाबेस या स्टोरेज की जगह, जिसे यूआरआई पाथ के तौर पर दिखाया जाता है.
  • नियम: allow स्टेटमेंट, जिसमें एक शर्त शामिल होती है. अगर यह शर्त सही होती है, तो अनुरोध को अनुमति दी जाती है.

मिलते-जुलते पाथ

Cloud Storage Security Rules match Cloud Storage में फ़ाइलों को ऐक्सेस करने के लिए इस्तेमाल किए जाने वाले फ़ाइल पाथ. नियमों में match सटीक पाथ या वाइल्डकार्ड पाथ शामिल किए जा सकते हैं. साथ ही, नियमों को नेस्ट भी किया जा सकता है. अगर मैच करने वाले किसी नियम में अनुरोध के तरीके की अनुमति नहीं है या शर्त की वैल्यू false है, तो अनुरोध अस्वीकार कर दिया जाता है.

एग्ज़ैक्ट मैच

// Exact match for "images/profilePhoto.png"
match /images/profilePhoto.png {
  allow write: if <condition>;
}

// Exact match for "images/croppedProfilePhoto.png"
match /images/croppedProfilePhoto.png {
  allow write: if <other_condition>;
}

नेस्ट किए गए मैच

// Partial match for files that start with "images"
match /images {
  // Exact match for "images/profilePhoto.png"
  match /profilePhoto.png {
    allow write: if <condition>;
  }

  // Exact match for "images/croppedProfilePhoto.png"
  match /croppedProfilePhoto.png {
    allow write: if <other_condition>;
  }
}

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

नियमों का इस्तेमाल, वाइल्डकार्ड का इस्तेमाल करके किसी पैटर्न को match करने के लिए भी किया जा सकता है. वाइल्डकार्ड, नाम वाला एक वैरिएबल होता है. यह profilePhoto.png जैसी एक स्ट्रिंग या images/profilePhoto.png जैसे कई पाथ सेगमेंट को दिखाता है.

वाइल्डकार्ड बनाने के लिए, वाइल्डकार्ड के नाम के चारों ओर कर्ली ब्रैकेट जोड़ें, जैसे कि {string}. एक से ज़्यादा सेगमेंट वाले वाइल्डकार्ड का एलान करने के लिए, वाइल्डकार्ड के नाम में =** जोड़ें, जैसे कि {path=**}:

// Partial match for files that start with "images"
match /images {
  // Exact match for "images/*"
  // e.g. images/profilePhoto.png is matched
  match /{imageId} {
    // This rule only matches a single path segment (*)
    // imageId is a string that contains the specific segment matched
    allow read: if <condition>;
  }

  // Exact match for "images/**"
  // e.g. images/users/user:12345/profilePhoto.png is matched
  // images/profilePhoto.png is also matched!
  match /{allImages=**} {
    // This rule matches one or more path segments (**)
    // allImages is a path that contains all segments matched
    allow read: if <other_condition>;
  }
}

अगर एक से ज़्यादा नियम किसी फ़ाइल से मैच करते हैं, तो नतीजा सभी नियमों के आकलन के नतीजे का OR होता है. इसका मतलब है कि अगर फ़ाइल किसी नियम से मैच करती है और उसका आकलन true के तौर पर किया जाता है, तो नतीजा true होगा.

ऊपर दिए गए नियमों के मुताबिक, "images/profilePhoto.png" फ़ाइल को तब ही पढ़ा जा सकता है, जब condition या other_condition का आकलन 'सही' के तौर पर किया गया हो. वहीं, "images/users/user:12345/profilePhoto.png" फ़ाइल को सिर्फ़ other_condition के नतीजे के हिसाब से पढ़ा जा सकता है.

match फ़ाइल का नाम या पाथ अनुमति देने वाले फ़ंक्शन में, वाइल्डकार्ड वैरिएबल का रेफ़रंस दिया जा सकता है:

// Another way to restrict the name of a file
match /images/{imageId} {
  allow read: if imageId == "profilePhoto.png";
}

Cloud Storage Security Rules कैस्केड नहीं करते हैं. साथ ही, नियमों का आकलन सिर्फ़ तब किया जाता है, जब अनुरोध पाथ, नियमों वाले पाथ से मेल खाता हो.

आकलन का अनुरोध करना

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

request ऑब्जेक्ट में उपयोगकर्ता का यूनीक आईडी और request.auth ऑब्जेक्ट में Firebase Authentication पेलोड भी होता है. इस बारे में ज़्यादा जानकारी, दस्तावेज़ों के पुष्टि सेक्शन में दी गई है.

request ऑब्जेक्ट में मौजूद प्रॉपर्टी की पूरी सूची यहां दी गई है:

प्रॉपर्टी टाइप ब्यौरा
auth map<string, string> जब कोई उपयोगकर्ता लॉग इन होता है, तो uid, उपयोगकर्ता का यूनीक आईडी और token, Firebase Authentication जेडब्लयूटी दावों का मैप उपलब्ध कराता है. ऐसा न करने पर, यह null होगा.
params map<string, string> अनुरोध के क्वेरी पैरामीटर वाला मैप.
path पाथ path, उस पाथ को दिखाता है जहां अनुरोध किया जा रहा है.
resource map<string, string> नई संसाधन वैल्यू, सिर्फ़ write अनुरोधों पर मौजूद होती है.
time timestamp टाइमस्टैंप, सर्वर के उस समय को दिखाता है जब अनुरोध का आकलन किया जाता है.

संसाधन का आकलन

नियमों का आकलन करते समय, अपलोड की जा रही, डाउनलोड की जा रही, बदली जा रही या मिटाई जा रही फ़ाइल के मेटाडेटा का आकलन भी किया जा सकता है. इसकी मदद से, जटिल और बेहतर नियम बनाए जा सकते हैं. जैसे, सिर्फ़ कुछ तरह के कॉन्टेंट वाली फ़ाइलों को अपलोड करने की अनुमति देना या सिर्फ़ तय साइज़ से बड़ी फ़ाइलों को मिटाना.

Cloud Storage के लिए Firebase Security Rules, resource ऑब्जेक्ट में फ़ाइल का मेटाडेटा उपलब्ध कराता है. इसमें Cloud Storage ऑब्जेक्ट में दिखाए गए मेटाडेटा के की/वैल्यू पेयर शामिल होते हैं. डेटा की अखंडता को पक्का करने के लिए, इन प्रॉपर्टी की जांच read या write अनुरोधों पर की जा सकती है.

write अनुरोधों (जैसे, अपलोड, मेटाडेटा अपडेट, और मिटाना) पर, resource ऑब्जेक्ट के अलावा, आपके पास request.resource ऑब्जेक्ट का इस्तेमाल करने का विकल्प भी होता है. resource ऑब्जेक्ट में, फ़ाइल के उस मेटाडेटा की जानकारी होती है जो फ़िलहाल अनुरोध पाथ पर मौजूद है. वहीं, request.resource ऑब्जेक्ट में, फ़ाइल के उस मेटाडेटा का सबसेट होता है जिसे लिखने की अनुमति होने पर लिखा जाता है. इन दोनों वैल्यू का इस्तेमाल, डेटा की सुरक्षा या फ़ाइल टाइप या साइज़ जैसी ऐप्लिकेशन की पाबंदियों को लागू करने के लिए किया जा सकता है.

resource ऑब्जेक्ट में मौजूद प्रॉपर्टी की पूरी सूची यहां दी गई है:

प्रॉपर्टी टाइप ब्यौरा
name स्ट्रिंग ऑब्जेक्ट का पूरा नाम
bucket स्ट्रिंग उस बकेट का नाम जिसमें यह ऑब्जेक्ट मौजूद है.
generation int इस ऑब्जेक्ट का Google Cloud Storage जनरेशन.
metageneration int इस ऑब्जेक्ट का Google Cloud Storage ऑब्जेक्ट मेटाजनरेशन.
size int ऑब्जेक्ट का साइज़, बाइट में.
timeCreated timestamp टाइमस्टैंप, जिससे पता चलता है कि ऑब्जेक्ट कब बनाया गया था.
updated timestamp टाइमस्टैंप, जिससे पता चलता है कि किसी ऑब्जेक्ट को आखिरी बार कब अपडेट किया गया था.
md5Hash स्ट्रिंग ऑब्जेक्ट का MD5 हैश.
crc32c स्ट्रिंग ऑब्जेक्ट का crc32c हैश.
etag स्ट्रिंग इस ऑब्जेक्ट से जुड़ा etag.
contentDisposition स्ट्रिंग इस ऑब्जेक्ट से जुड़ा कॉन्टेंट डिस्पोज़िशन.
contentEncoding स्ट्रिंग इस ऑब्जेक्ट से जुड़ा कॉन्टेंट कोड.
contentLanguage स्ट्रिंग इस ऑब्जेक्ट से जुड़े कॉन्टेंट की भाषा.
contentType स्ट्रिंग इस ऑब्जेक्ट से जुड़ा कॉन्टेंट टाइप.
metadata map<string, string> डेवलपर के तय किए गए अतिरिक्त कस्टम मेटाडेटा के की/वैल्यू पेयर.

request.resource में generation, metageneration, etag, timeCreated, और updated को छोड़कर ये सभी शामिल हैं.

सुरक्षा के नियमों की सीमाएं

सुरक्षा से जुड़े नियमों के साथ काम करते समय, इन सीमाओं का ध्यान रखें:

सीमा विवरण
हर अनुरोध के लिए, firestore.exists() और firestore.get() कॉल की ज़्यादा से ज़्यादा संख्या

एक दस्तावेज़ के अनुरोध और क्वेरी के अनुरोध के लिए दो.

इस सीमा से ज़्यादा डेटा अपलोड करने पर, 'अनुमति नहीं दी गई' गड़बड़ी का मैसेज दिखता है.

एक ही दस्तावेज़ के ऐक्सेस कॉल को कैश मेमोरी में सेव किया जा सकता है. साथ ही, कैश मेमोरी में सेव किए गए कॉल की संख्या, सीमाओं में शामिल नहीं की जाती.

पूरा उदाहरण

इन सभी बातों को ध्यान में रखते हुए, इमेज स्टोरेज के समाधान के लिए नियमों का पूरा उदाहरण बनाया जा सकता है:

service firebase.storage {
 match /b/{bucket}/o {
   match /images {
     // Cascade read to any image type at any path
     match /{allImages=**} {
       allow read;
     }

     // Allow write files to the path "images/*", subject to the constraints:
     // 1) File is less than 5MB
     // 2) Content type is an image
     // 3) Uploaded content type matches existing content type
     // 4) File name (stored in imageId wildcard variable) is less than 32 characters
     match /{imageId} {
       allow write: if request.resource.size < 5 * 1024 * 1024
                    && request.resource.contentType.matches('image/.*')
                    && request.resource.contentType == resource.contentType
                    && imageId.size() < 32
     }
   }
 }
}

Realtime Database

बुनियादी स्ट्रक्चर

Realtime Database में, Firebase Security Rules में JavaScript जैसे एक्सप्रेशन होते हैं, जो किसी JSON दस्तावेज़ में मौजूद होते हैं.

इनमें इस सिंटैक्स का इस्तेमाल किया जाता है:

{
  "rules": {
    "<<path>>": {
    // Allow the request if the condition for each method is true.
      ".read": <<condition>>,
      ".write": <<condition>>,
      ".validate": <<condition>>
    }
  }
}

नियम में तीन बुनियादी एलिमेंट होते हैं:

  • पाथ: डेटाबेस की जगह. यह आपके डेटाबेस के JSON स्ट्रक्चर को दिखाता है.
  • अनुरोध: ये ऐसे तरीके हैं जिनका इस्तेमाल करके नियम, ऐक्सेस देता है. read और write नियमों से, डेटा को पढ़ने और उसमें बदलाव करने का ज़्यादा ऐक्सेस मिलता है. वहीं, validate नियम, आने वाले या मौजूदा डेटा के आधार पर ऐक्सेस देने के लिए, दूसरी पुष्टि के तौर पर काम करते हैं.
  • शर्त: यह शर्त, अनुरोध को तब अनुमति देती है, जब वह सही हो.

पाथ पर नियम कैसे लागू होते हैं

Realtime Database में, Rules एक-एक करके लागू होते हैं. इसका मतलब है कि ज़्यादा लेवल वाले पैरंट नोड के नियम, ज़्यादा जानकारी वाले चाइल्ड नोड के नियमों को बदल देते हैं. साथ ही, किसी गहरे नोड के नियम, पैरंट पाथ का ऐक्सेस नहीं दे सकते. अगर आपने किसी पैरंट पाथ के लिए पहले ही ऐक्सेस दिया है, तो डेटाबेस के स्ट्रक्चर में किसी गहरे पाथ के लिए, ऐक्सेस को बेहतर नहीं बनाया जा सकता या उसे रद्द नहीं किया जा सकता.

इन नियमों का पालन करें:

{
  "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 शामिल हो. /foo/bar/ में दिए गए ".read": false नियम का यहां कोई असर नहीं पड़ता, क्योंकि चाइल्ड पाथ से ऐक्सेस रद्द नहीं किया जा सकता.

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

हालांकि, .validate नियम कैस्केड नहीं होते. डेटा में बदलाव करने की अनुमति देने के लिए, पुष्टि करने वाले सभी नियमों को हैरारकी के सभी लेवल पर पूरा करना ज़रूरी है.

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

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

यह समझे बिना कि नियमों का आकलन एक-एक करके किया जाता है, ऐसा लग सकता है कि /records/ पाथ को फ़ेच करने पर rec1 दिखेगा, लेकिन rec2 नहीं. हालांकि, असल नतीजा गड़बड़ी है:

JavaScript
var db = firebase.database();
db.ref("records").once("value", function(snap) {
  // success method is not called
}, function(err) {
  // error callback triggered with PERMISSION_DENIED
});
Objective-C
ध्यान दें: Firebase का यह प्रॉडक्ट, ऐप्लिकेशन क्लिप टारगेट पर उपलब्ध नहीं है.
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
}];
Swift
ध्यान दें: Firebase का यह प्रॉडक्ट, ऐप्लिकेशन क्लिप टारगेट पर उपलब्ध नहीं है.
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
})
Java
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
  });
});
REST
curl https://docs-examples.firebaseio.com/rest/records/
# response returns a PERMISSION_DENIED error

/records/ में, डेटा पढ़ने की कार्रवाई एक बार में पूरी होती है. साथ ही, /records/ में मौजूद सभी डेटा को ऐक्सेस करने की अनुमति देने वाला कोई नियम नहीं है. इसलिए, इससे PERMISSION_DENIED गड़बड़ी का मैसेज दिखेगा. अगर हम अपने Firebase कंसोल में सुरक्षा सिम्युलेटर में इस नियम का आकलन करते हैं, तो हमें पता चलता है कि पढ़ने की अनुमति अस्वीकार कर दी गई थी:

Attempt to read /records with auth=Success(null)
    /
    /records

No .read rule allowed the operation.
Read was denied.

कार्रवाई अस्वीकार कर दी गई, क्योंकि पढ़ने के लिए बने किसी भी नियम ने /records/ पाथ को ऐक्सेस करने की अनुमति नहीं दी. हालांकि, ध्यान दें कि rec1 के लिए बने नियम का कभी आकलन नहीं किया गया, क्योंकि वह उस पाथ में नहीं था जिसके लिए हमने अनुरोध किया था. rec1 को फ़ेच करने के लिए, हमें इसे सीधे ऐक्सेस करना होगा:

JavaScript
var db = firebase.database();
db.ref("records/rec1").once("value", function(snap) {
  // SUCCESS!
}, function(err) {
  // error callback is not called
});
Objective-C
ध्यान दें: Firebase का यह प्रॉडक्ट, ऐप्लिकेशन क्लिप टारगेट पर उपलब्ध नहीं है.
FIRDatabaseReference *ref = [[FIRDatabase database] reference];
[[ref child:@"records/rec1"] observeSingleEventOfType:FEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) {
    // SUCCESS!
}];
Swift
ध्यान दें: Firebase का यह प्रॉडक्ट, ऐप्लिकेशन क्लिप टारगेट पर उपलब्ध नहीं है.
var ref = FIRDatabase.database().reference()
ref.child("records/rec1").observeSingleEventOfType(.Value, withBlock: { snapshot in
    // SUCCESS!
})
Java
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
  }
});
REST
curl https://docs-examples.firebaseio.com/rest/records/rec1
# SUCCESS!

जगह की जानकारी वाला वैरिएबल

Realtime Database Rules, पाथ सेगमेंट से मैच करने के लिए $location वैरिएबल का इस्तेमाल करता है. अपने पाथ सेगमेंट के आगे $ प्रीफ़िक्स का इस्तेमाल करें, ताकि आपके नियम को पाथ के किसी भी चाइल्ड नोड से मैच किया जा सके.

  {
    "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')"
          }
        }
      }
    }
  }

$variable का इस्तेमाल, पाथ के नामों के साथ भी किया जा सकता है.

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