सुरक्षा, ऐप्लिकेशन डेवलपमेंट की पहेली का सबसे मुश्किल हिस्सा हो सकता है. ज़्यादातर ऐप्लिकेशन में, डेवलपर को एक ऐसा सर्वर बनाना और चलाना होता है जो पुष्टि (उपयोगकर्ता कौन है) और अनुमति (उपयोगकर्ता क्या कर सकता है) को मैनेज करता है.
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 से, Security Rules के सुरक्षा नियमों का दूसरा वर्शन उपलब्ध है. नियमों के दूसरे वर्शन में, रिकर्सिव वाइल्डकार्ड {name=**} के व्यवहार में बदलाव किया गया है. अगर आपको कलेक्शन ग्रुप क्वेरी का इस्तेमाल करना है, तो आपको वर्शन 2 का इस्तेमाल करना होगा. आपको वर्शन 2 के लिए ऑप्ट-इन करना होगा. इसके लिए, सुरक्षा नियमों में rules_version = '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>;
}
}
}
मिलान की शर्तों का एक-दूसरे से मेल खाना
ऐसा हो सकता है कि कोई दस्तावेज़ एक से ज़्यादा 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.
match /cities/{document} {
allow read, write: if true;
}
}
}
इस उदाहरण में, cities कलेक्शन में सभी रीड और राइट की अनुमति होगी, क्योंकि दूसरा नियम हमेशा true होता है. भले ही, पहला नियम हमेशा false होता है.
बार-बार इस्तेमाल होने वाले वाइल्डकार्ड
अगर आपको नियमों को किसी भी लेवल की डीप हाइरार्की पर लागू करना है, तो रिकर्सिव वाइल्डकार्ड सिंटैक्स {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 का इस्तेमाल करते हैं. वर्शन 1 में, रिकर्सिव वाइल्डकार्ड, एक या उससे ज़्यादा पाथ आइटम से मेल खाते हैं. ये खाली पाथ से मेल नहीं खाते. इसलिए, match /cities/{city}/{document=**} सब-कलेक्शन में मौजूद दस्तावेज़ों से मेल खाता है, लेकिन cities कलेक्शन में मौजूद दस्तावेज़ों से नहीं. वहीं, match /cities/{document=**}, cities कलेक्शन और सब-कलेक्शन, दोनों में मौजूद दस्तावेज़ों से मेल खाता है.
रिकर्सिव वाइल्डकार्ड, मैच स्टेटमेंट के आखिर में होने चाहिए.
वर्शन 2
सुरक्षा नियमों के वर्शन 2 में, रिकर्सिव वाइल्डकार्ड, पाथ के शून्य या उससे ज़्यादा आइटम से मेल खाते हैं. match/cities/{city}/{document=**}, किसी भी सब-कलेक्शन के साथ-साथ cities कलेक्शन में मौजूद दस्तावेज़ों से भी मेल खाता है.
आपको वर्शन 2 में ऑप्ट-इन करना होगा. इसके लिए, सुरक्षा नियमों के सबसे ऊपर rules_version = '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>;
}
}
}
हर मैच स्टेटमेंट में, ज़्यादा से ज़्यादा एक रिकर्सिव वाइल्डकार्ड हो सकता है. हालांकि, वर्शन 2 में इस वाइल्डकार्ड को मैच स्टेटमेंट में कहीं भी रखा जा सकता है. उदाहरण के लिए:
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 का इस्तेमाल करना होगा. कलेक्शन ग्रुप क्वेरी को सुरक्षित करने के बारे में जानें.
सुरक्षा के नियमों की सीमाएं
सुरक्षा के नियमों का इस्तेमाल करते समय, इन सीमाओं का ध्यान रखें:
| सीमा | विवरण |
|---|---|
हर अनुरोध के लिए, ज़्यादा से ज़्यादा exists(), get(), और getAfter() कॉल किए जा सकते हैं |
इनमें से किसी भी सीमा को पार करने पर, अनुमति नहीं दी जाएगी. दस्तावेज़ के ऐक्सेस से जुड़े कुछ कॉल को कैश मेमोरी में सेव किया जा सकता है. कैश मेमोरी में सेव किए गए कॉल, सीमा में शामिल नहीं किए जाते. |
नेस्ट किए गए match स्टेटमेंट की ज़्यादा से ज़्यादा गहराई |
10 |
नेस्ट किए गए match स्टेटमेंट के सेट में, पाथ सेगमेंट में पाथ की ज़्यादा से ज़्यादा लंबाई |
100 |
नेस्ट किए गए match स्टेटमेंट के सेट में, ज़्यादा से ज़्यादा पाथ कैप्चर वैरिएबल इस्तेमाल किए जा सकते हैं |
20 |
| फ़ंक्शन कॉल की ज़्यादा से ज़्यादा डेप्थ | 20 |
| फ़ंक्शन के आर्ग्युमेंट की ज़्यादा से ज़्यादा संख्या | 7 |
हर फ़ंक्शन के लिए, ज़्यादा से ज़्यादा let वैरिएबल बाइंडिंग |
10 |
| बार-बार या साइकल के हिसाब से फ़ंक्शन कॉल की ज़्यादा से ज़्यादा संख्या | 0 (अनुमति नहीं है) |
| हर अनुरोध के लिए, आकलन किए गए एक्सप्रेशन की ज़्यादा से ज़्यादा संख्या | 1,000 |
| नियमों के सेट का ज़्यादा से ज़्यादा साइज़ | नियमों के सेट के लिए, साइज़ की दो सीमाएं तय की गई हैं:
|
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 provide filename
या path authorization में जाकर रेफ़रंस किया जा सकता है:
// Another way to restrict the name of a file match /images/{imageId} { allow read: if imageId == "profilePhoto.png"; }
Cloud Storage Security Rules कैस्केड नहीं होते हैं. साथ ही, नियमों का आकलन सिर्फ़ तब किया जाता है, जब अनुरोध का पाथ, नियमों के साथ तय किए गए पाथ से मेल खाता हो.
आकलन का अनुरोध करना
अपलोड, डाउनलोड, मेटाडेटा में बदलाव, और मिटाने की कार्रवाइयों का आकलन करने के लिए, request का इस्तेमाल किया जाता है. इसे Cloud Storage को भेजा जाता है. request वैरिएबल में, अनुरोध किए जाने का पाथ, अनुरोध मिलने का समय, और अगर अनुरोध लिखने का है, तो resource की नई वैल्यू शामिल होती है. इसमें एचटीटीपी हेडर और पुष्टि करने की स्थिति भी शामिल होती है.
request ऑब्जेक्ट में उपयोगकर्ता का यूनीक आईडी और request.auth ऑब्जेक्ट में Firebase Authentication पेलोड भी होता है. इसके बारे में दस्तावेज़ के पुष्टि करना सेक्शन में ज़्यादा जानकारी दी गई है.
request ऑब्जेक्ट में मौजूद प्रॉपर्टी की पूरी सूची यहां दी गई है:
| प्रॉपर्टी | टाइप | ब्यौरा |
|---|---|---|
auth |
map<string, string> | जब कोई उपयोगकर्ता लॉग इन होता है, तो यह कुकी uid, उपयोगकर्ता का यूनीक आईडी, और token, Firebase Authentication JWT के दावों का मैप उपलब्ध कराती है. ऐसा न करने पर, यह 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 अनुरोधों पर, आपके पास request.resource ऑब्जेक्ट का इस्तेमाल करने का विकल्प भी होता है. इसमें फ़ाइल के मेटाडेटा का सबसेट होता है. इसे तब लिखा जाता है, जब लिखने की अनुमति हो. इसके अलावा, आपके पास 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 |
स्ट्रिंग | इस ऑब्जेक्ट से जुड़ा ईटैग. |
contentDisposition |
स्ट्रिंग | इस ऑब्जेक्ट से जुड़ा कॉन्टेंट डिसपोज़िशन. |
contentEncoding |
स्ट्रिंग | इस ऑब्जेक्ट से जुड़ी कॉन्टेंट एन्कोडिंग. |
contentLanguage |
स्ट्रिंग | इस ऑब्जेक्ट से जुड़ी कॉन्टेंट की भाषा. |
contentType |
स्ट्रिंग | इस ऑब्जेक्ट से जुड़ा कॉन्टेंट टाइप. |
metadata |
map<string, string> | डेवलपर के तय किए गए कस्टम मेटाडेटा के अतिरिक्त की/वैल्यू पेयर. |
request.resource में ये सभी शामिल हैं. हालांकि, इसमें generation, metageneration, etag, timeCreated, और updated शामिल नहीं हैं.
सुरक्षा के नियमों से जुड़ी सीमाएं
सुरक्षा के नियमों का इस्तेमाल करते समय, इन सीमाओं का ध्यान रखें:
| सीमा | विवरण |
|---|---|
हर अनुरोध के लिए, ज़्यादा से ज़्यादा firestore.exists() और
firestore.get() कॉल |
एक दस्तावेज़ के अनुरोध और क्वेरी के अनुरोधों के लिए 2. इस सीमा से ज़्यादा अनुरोध करने पर, अनुमति नहीं दी जाएगी. एक ही दस्तावेज़ को ऐक्सेस करने के अनुरोधों को कैश मेमोरी में सेव किया जा सकता है. कैश मेमोरी में सेव किए गए अनुरोध, सीमा में शामिल नहीं किए जाते. |
पूरा उदाहरण
इन सभी को एक साथ रखकर, इमेज स्टोरेज की सुविधा के लिए नियमों का पूरा उदाहरण बनाया जा सकता है:
service firebase.storage { match /b/{bucket}/o { match /images { // 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) Filename (stored in imageId wildcard variable) is less than 32 characters match /{imageId} { allow read; 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 में, Security 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
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
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
FIRDatabaseReference *ref = [[FIRDatabase database] reference]; [[ref child:@"records/rec1"] observeSingleEventOfType:FEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) { // SUCCESS! }];
Swift
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 Security 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 }
}
}
}