सुरक्षा, ऐप्लिकेशन डेवलपमेंट की सबसे मुश्किल पहेलियों में से एक हो सकती है. ज़्यादातर ऐप्लिकेशन में, डेवलपर को एक ऐसा सर्वर बनाना और चलाना होता है जो पुष्टि (उपयोगकर्ता कौन है) और अनुमति (उपयोगकर्ता क्या कर सकता है) को मैनेज करता है.
Firebase Security Rules से सर्वर लेयर हट जाती है. साथ ही, आपको उन क्लाइंट के लिए पाथ के आधार पर अनुमतियां तय करने की सुविधा मिलती है जो सीधे तौर पर आपके डेटा से कनेक्ट होते हैं. इस गाइड का इस्तेमाल करके, इस बारे में ज़्यादा जानें कि आने वाले अनुरोधों पर नियम कैसे लागू होते हैं.
किसी प्रॉडक्ट को चुनकर, उसके नियमों के बारे में ज़्यादा जानें.
Cloud Firestore
बुनियादी स्ट्रक्चर
Firebase Security Rules में Cloud Firestore और Cloud Storage के लिए, इस स्ट्रक्चर और सिंटैक्स का इस्तेमाल करें:
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 का इस्तेमाल करना होगा. आपको वर्शन 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
कलेक्शन पर तय किए गए ऐक्सेस कंट्रोल, 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() को ज़्यादा से ज़्यादा exists() बार कॉल किया जा सकता है |
इनमें से किसी भी सीमा को पार करने पर, अनुमति नहीं दी जाएगी. दस्तावेज़ के ऐक्सेस से जुड़े कुछ कॉल को कैश मेमोरी में सेव किया जा सकता है. कैश मेमोरी में सेव किए गए कॉल, सीमा में शामिल नहीं किए जाते. |
नेस्ट किए गए match स्टेटमेंट की ज़्यादा से ज़्यादा गहराई |
10 |
नेस्ट किए गए match स्टेटमेंट के सेट में, पाथ सेगमेंट में पाथ की ज़्यादा से ज़्यादा लंबाई |
100 |
नेस्ट किए गए match स्टेटमेंट के सेट में, पाथ कैप्चर करने वाले वैरिएबल की ज़्यादा से ज़्यादा संख्या |
20 |
फ़ंक्शन कॉल की ज़्यादा से ज़्यादा डेप्थ | 20 |
फ़ंक्शन के आर्ग्युमेंट की ज़्यादा से ज़्यादा संख्या | 7 |
हर फ़ंक्शन के लिए, let वैरिएबल बाइंडिंग की ज़्यादा से ज़्यादा संख्या |
10 |
रिकर्सिव या साइक्लिक फ़ंक्शन कॉल की ज़्यादा से ज़्यादा संख्या | 0 (अनुमति नहीं है) |
हर अनुरोध के लिए, आकलन किए गए एक्सप्रेशन की ज़्यादा से ज़्यादा संख्या | 1,000 |
नियमों के सेट का ज़्यादा से ज़्यादा साइज़ | नियमों के सेट के लिए, साइज़ से जुड़ी दो सीमाएं तय की गई हैं. इनका पालन करना ज़रूरी है:
|
Cloud Storage
बुनियादी स्ट्रक्चर
Firebase Security Rules में Cloud Firestore और Cloud Storage के लिए, इस स्ट्रक्चर और सिंटैक्स का इस्तेमाल करें:
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 कैस्केड नहीं होते हैं. साथ ही, नियमों का आकलन सिर्फ़ तब किया जाता है, जब अनुरोध का पाथ, नियमों के साथ बताए गए पाथ से मेल खाता हो.
इवैलुएशन का अनुरोध करना
अपलोड, डाउनलोड, मेटाडेटा में बदलाव, और मिटाने के अनुरोधों का आकलन करने के लिए, 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
अनुरोधों (जैसे कि अपलोड, मेटाडेटा अपडेट, और मिटाना) पर, 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 |
स्ट्रिंग | इस ऑब्जेक्ट से जुड़ा ईटैग. |
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 में, Rules एक साथ लागू होते हैं. इसका मतलब है कि पैरंट नोड के नियमों को चाइल्ड नोड के नियमों पर प्राथमिकता मिलती है. साथ ही, किसी नोड के नियमों के तहत पैरंट पाथ को ऐक्सेस करने की अनुमति नहीं दी जा सकती. अगर आपने डेटाबेस के किसी पैरंट पाथ के लिए पहले ही ऐक्सेस दे दिया है, तो डेटाबेस स्ट्रक्चर के किसी डीपर पाथ के लिए ऐक्सेस को बेहतर नहीं बनाया जा सकता या उसे रद्द नहीं किया जा सकता.
इन नियमों का पालन करें:
{ "rules": { "foo": { // allows read to /foo/* ".read": "data.child('baz').val() === true", "bar": { // ignored, since read was allowed already ".read": false } } } }
इस सुरक्षा स्ट्रक्चर की मदद से, /bar/
को तब पढ़ा जा सकता है, जब /foo/
में baz
मौजूद हो और उसकी वैल्यू true
हो.
/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 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 }
}
}
}