Firebase Cloud Storage के सुरक्षा नियमों में शर्तों का इस्तेमाल करना

यह गाइड, भाषा के मुख्य सिंटैक्स के बारे में बताने वाली गाइड पर आधारित है. इसमें Firebase Security Rules के लिए, Cloud Storage में शर्तें जोड़ने का तरीका बताया गया है.Firebase Security Rules

Cloud Storage Security Rules का मुख्य बिल्डिंग ब्लॉक शर्त होती है. शर्त, बूलियन एक्सप्रेशन होती है. इससे यह तय होता है कि किसी खास कार्रवाई की अनुमति दी जानी चाहिए या नहीं. बुनियादी नियमों के लिए, true और false लिटरल का इस्तेमाल, शर्तों के तौर पर किया जा सकता है. हालांकि, Firebase Security Rules के लिए Cloud Storage भाषा से, ज़्यादा जटिल शर्तें लिखी जा सकती हैं. इन शर्तों से ये काम किए जा सकते हैं:

  • उपयोगकर्ता की पुष्टि की जांच करना
  • आने वाले डेटा की पुष्टि करना

पुष्टि करना

Firebase Security Rules के लिए Cloud Storage, Firebase Authentication के साथ इंटिग्रेट होती है. इससे Cloud Storage के लिए, उपयोगकर्ता के आधार पर पुष्टि करने की सुविधा मिलती है. इससे, टोकन के दावों के आधार पर, ऐक्सेस को बेहतर तरीके से कंट्रोल किया जा सकता है.Firebase Authentication

जब पुष्टि किया गया कोई उपयोगकर्ता, Cloud Storage के लिए अनुरोध करता है, तो request.auth वैरिएबल में उपयोगकर्ता का uid (request.auth.uid) और Firebase Authentication जेडब्लयूटी (request.auth.token) के दावे शामिल होते हैं.

इसके अलावा, पसंद के मुताबिक पुष्टि करने की सुविधा का इस्तेमाल करने पर, request.auth.token फ़ील्ड में अतिरिक्त दावे दिखते हैं.

जब पुष्टि नहीं किया गया कोई उपयोगकर्ता अनुरोध करता है, तो request.auth वैरिएबल null होता है.

इस डेटा का इस्तेमाल करके, फ़ाइलों को सुरक्षित रखने के लिए, पुष्टि करने की सुविधा का इस्तेमाल कई सामान्य तरीकों से किया जा सकता है:

  • कोई भी देख सकता है: request.auth को अनदेखा करें
  • पुष्टि किया गया उपयोगकर्ता ही देख सकता है: जांच करें कि request.auth null नहीं है
  • उपयोगकर्ता ही देख सकता है: जांच करें कि request.auth.uid, पाथ uid के बराबर है
  • ग्रुप के सदस्य ही देख सकते हैं: चुने गए दावे से मेल खाने के लिए, कस्टम टोकन के दावों की जांच करें या यह देखने के लिए फ़ाइल का मेटाडेटा पढ़ें कि कोई मेटाडेटा फ़ील्ड मौजूद है या नहीं

कोई भी देख सकता है

जिस नियम में request.auth कॉन्टेक्स्ट को ध्यान में नहीं रखा जाता उसे public नियम माना जा सकता है. ऐसा इसलिए, क्योंकि इसमें उपयोगकर्ता के पुष्टि करने के कॉन्टेक्स्ट को ध्यान में नहीं रखा जाता. ये नियम, सार्वजनिक डेटा दिखाने के लिए काम के हो सकते हैं. जैसे, गेम की एसेट, साउंड फ़ाइलें या अन्य स्टैटिक कॉन्टेंट.

// Anyone to read a public image if the file is less than 100kB
// Anyone can upload a public file ending in '.txt'
match /public/{imageId} {
  allow read: if resource.size < 100 * 1024;
  allow write: if imageId.matches(".*\\.txt");
}

पुष्टि किया गया उपयोगकर्ता ही देख सकता है

कुछ मामलों में, हो सकता है कि आपको यह तय करना हो कि आपके ऐप्लिकेशन के पुष्टि किए गए सभी उपयोगकर्ता डेटा देख सकें, लेकिन पुष्टि नहीं किए गए उपयोगकर्ता नहीं. पुष्टि नहीं किए गए सभी उपयोगकर्ताओं के लिए, request.auth वैरिएबल null होता है. इसलिए, पुष्टि करने की ज़रूरत के लिए, आपको सिर्फ़ यह जांच करनी होती है कि request.auth वैरिएबल मौजूद है या नहीं:

// Require authentication on all internal image reads
match /internal/{imageId} {
  allow read: if request.auth != null;
}

उपयोगकर्ता ही देख सकता है

request.auth का सबसे सामान्य इस्तेमाल, अलग-अलग उपयोगकर्ताओं को उनकी फ़ाइलों पर बेहतर अनुमतियां देना है. जैसे, प्रोफ़ाइल फ़ोटो अपलोड करने से लेकर निजी दस्तावेज़ पढ़ने तक.

Cloud Storage में मौजूद फ़ाइलों का पूरा "पाथ" होता है. इसलिए, किसी फ़ाइल को उपयोगकर्ता के कंट्रोल में लाने के लिए, फ़ाइल नाम के प्रीफ़िक्स में उपयोगकर्ता की पहचान करने वाली यूनीक जानकारी (जैसे, उपयोगकर्ता का uid) शामिल करनी होती है. नियम का आकलन करते समय, इसकी जांच की जा सकती है:

// Only a user can upload their profile picture, but anyone can view it
match /users/{userId}/profilePicture.png {
  allow read;
  allow write: if request.auth.uid == userId;
}

ग्रुप के सदस्य ही देख सकते हैं

एक और सामान्य इस्तेमाल, किसी ऑब्जेक्ट पर ग्रुप की अनुमतियां देना है. जैसे, टीम के कई सदस्यों को शेयर किए गए दस्तावेज़ पर मिलकर काम करने की अनुमति देना. इसके लिए, कई तरीके अपनाए जा सकते हैं:

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

टोकन या फ़ाइल के मेटाडेटा में यह डेटा सेव होने के बाद, इसे किसी नियम में रेफ़र किया जा सकता है:

// Allow reads if the group ID in your token matches the file metadata's `owner` property
// Allow writes if the group ID is in the user's custom token
match /files/{groupId}/{fileName} {
  allow read: if resource.metadata.owner == request.auth.token.groupId;
  allow write: if request.auth.token.groupId == groupId;
}

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

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

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

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

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

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

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

Firebase Security Rules के लिए Cloud Storage, 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 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 शामिल नहीं होती हैं.

Cloud Firestore के साथ बेहतर बनाना

अनुमति से जुड़ी अन्य शर्तों का आकलन करने के लिए, Cloud Firestore में मौजूद दस्तावेज़ों को ऐक्सेस किया जा सकता है.

firestore.get() और firestore.exists() फ़ंक्शन का इस्तेमाल करके, सुरक्षा के नियम, Cloud Firestore में मौजूद दस्तावेज़ों के ख़िलाफ़ आने वाले अनुरोधों का आकलन कर सकते हैं. firestore.get() और firestore.exists() फ़ंक्शन, दोनों के लिए दस्तावेज़ के पूरे पाथ की ज़रूरत होती है. firestore.get() और firestore.exists() के लिए पाथ बनाने के लिए, वैरिएबल का इस्तेमाल करते समय, आपको $(variable) सिंटैक्स का इस्तेमाल करके, वैरिएबल को साफ़ तौर पर एस्केप करना होगा.

यहां दिए गए उदाहरण में, हम एक ऐसा नियम देखते हैं जो फ़ाइलों को पढ़ने का ऐक्सेस सिर्फ़ उन उपयोगकर्ताओं तक सीमित रखता है जो खास क्लब के सदस्य हैं.

service firebase.storage {
  match /b/{bucket}/o {
    match /users/{club}/files/{fileId} {
      allow read: if club in
        firestore.get(/databases/(default)/documents/users/$(request.auth.id)).data.memberships
    }
  }
}
अगले उदाहरण में, सिर्फ़ उपयोगकर्ता के दोस्त उसकी फ़ोटो देख सकते हैं.
service firebase.storage {
  match /b/{bucket}/o {
    match /users/{userId}/photos/{fileId} {
      allow read: if
        firestore.exists(/databases/(default)/documents/users/$(userId)/friends/$(request.auth.id))
    }
  }
}

Cloud Firestore के इन Cloud Firestore फ़ंक्शन का इस्तेमाल करके, अपना पहला Cloud Storage Security Rules बनाने और उसे सेव करने के बाद, Firebase कंसोल या Firebase सीएलआई में, दोनों प्रॉडक्ट को कनेक्ट करने के लिए अनुमतियां चालू करने का अनुरोध किया जाएगा.

IAM रोल हटाकर, इस सुविधा को बंद किया जा सकता है. इसके बारे में, Manage and deploy Firebase Security Rules लेख में बताया गया है.

डेटा की पुष्टि करना

Firebase Security Rules का इस्तेमाल, Cloud Storage के लिए डेटा की पुष्टि करने के लिए भी किया जा सकता है. इसमें फ़ाइल के नाम और पाथ के साथ-साथ, फ़ाइल के मेटाडेटा की प्रॉपर्टी की पुष्टि करना भी शामिल है. जैसे, contentType और size.

service firebase.storage {
  match /b/{bucket}/o {
    match /images/{imageId} {
      // Only allow uploads of any image file that's less than 5MB
      allow write: if request.resource.size < 5 * 1024 * 1024
                   && request.resource.contentType.matches('image/.*');
    }
  }
}

पसंद के मुताबिक फ़ंक्शन

आपके Firebase Security Rules के ज़्यादा जटिल होने पर, शर्तों के सेट को ऐसे फ़ंक्शन में रैप किया जा सकता है जिन्हें अपने नियमों के सेट में फिर से इस्तेमाल किया जा सके. सुरक्षा के नियम, पसंद के मुताबिक फ़ंक्शन के साथ काम करते हैं. पसंद के मुताबिक फ़ंक्शन का सिंटैक्स, JavaScript की तरह होता है, हालांकि, Firebase Security Rules फ़ंक्शन, डोमेन के लिए खास भाषा में लिखे जाते हैं इसकी कुछ अहम सीमाएं हैं:

  • फ़ंक्शन में सिर्फ़ एक return स्टेटमेंट हो सकता है. इसमें कोई अतिरिक्त लॉजिक नहीं हो सकता. उदाहरण के लिए, ये लूप नहीं चला सकते या बाहरी सेवाओं को कॉल नहीं कर सकते.
  • फ़ंक्शन, उस स्कोप से फ़ंक्शन और वैरिएबल को अपने-आप ऐक्सेस कर सकते हैं जिसमें उन्हें तय किया गया है. उदाहरण के लिए, service firebase.storage स्कोप में तय किए गए फ़ंक्शन के पास, resource वैरिएबल का ऐक्सेस होता है. साथ ही, Cloud Firestore के लिए, get() और exists() जैसे बिल्ट-इन फ़ंक्शन का ऐक्सेस होता है.
  • फ़ंक्शन, अन्य फ़ंक्शन को कॉल कर सकते हैं, लेकिन खुद को कॉल नहीं कर सकते. कॉल स्टैक की कुल डेप्थ 10 तक सीमित है.
  • rules2 वर्शन में, फ़ंक्शन, let कीवर्ड का इस्तेमाल करके वैरिएबल तय कर सकते हैं. फ़ंक्शन में, 'लेट बाइंडिंग' की कोई भी संख्या हो सकती है. हालांकि, यह 'रिटर्न स्टेटमेंट' के साथ खत्म होनी चाहिए.

किसी फ़ंक्शन को function कीवर्ड से तय किया जाता है. इसमें कोई भी आर्ग्युमेंट नहीं हो सकता या एक से ज़्यादा आर्ग्युमेंट हो सकते हैं. उदाहरण के लिए, ऊपर दिए गए उदाहरणों में इस्तेमाल की गई, दो तरह की शर्तों को एक ही फ़ंक्शन में जोड़ा जा सकता है:

service firebase.storage {
  match /b/{bucket}/o {
    // True if the user is signed in or the requested data is 'public'
    function signedInOrPublic() {
      return request.auth.uid != null || resource.data.visibility == 'public';
    }
    match /images/{imageId} {
      allow read, write: if signedInOrPublic();
    }
    match /mp3s/{mp3Ids} {
      allow read: if signedInOrPublic();
    }
  }
}

आपके Firebase Security Rules में फ़ंक्शन का इस्तेमाल करने से, नियमों की जटिलता बढ़ने पर भी उन्हें मैनेज करना आसान हो जाता है.

अगले चरण

शर्तों के बारे में इस चर्चा के बाद, आपको नियमों के बारे में ज़्यादा जानकारी मिल गई है. अब आप ये काम कर सकते हैं:

इस्तेमाल के मुख्य मामलों को हैंडल करने का तरीका जानें. साथ ही, नियम बनाने, उनकी जांच करने, और उन्हें डिप्लॉय करने का तरीका जानें: