Firebase ক্লাউড স্টোরেজ নিরাপত্তা নিয়মে শর্তাবলী ব্যবহার করুন

এই নির্দেশিকাটি Firebase Security Rules ভাষার মূল সিনট্যাক্স শেখার নির্দেশিকার উপর ভিত্তি করে দেখানো হয়েছে যে, কীভাবে আপনার Cloud Storage জন্য Firebase Security Rules এ শর্তাবলী যোগ করতে হয়।

Cloud Storage Security Rules এর প্রধান ভিত্তি হলো কন্ডিশন । কন্ডিশন হলো একটি বুলিয়ান এক্সপ্রেশন যা নির্ধারণ করে কোনো নির্দিষ্ট অপারেশন অনুমোদিত হবে নাকি প্রত্যাখ্যাত হবে। সাধারণ রুলসের জন্য, কন্ডিশন হিসেবে true এবং false লিটারেল ব্যবহার করাই যথেষ্ট। কিন্তু Cloud Storage জন্য Firebase Security Rules আপনাকে আরও জটিল কন্ডিশন লেখার উপায় দেয় যা:

  • ব্যবহারকারীর প্রমাণীকরণ যাচাই করুন
  • আগত ডেটা যাচাই করুন

প্রমাণীকরণ

Cloud Storage জন্য Firebase Security Rules Firebase Authentication সাথে সমন্বিত হয়ে Cloud Storage শক্তিশালী ব্যবহারকারী-ভিত্তিক অথেনটিকেশন প্রদান করে। এটি একটি Firebase Authentication টোকেনের ক্লেইমগুলোর উপর ভিত্তি করে সূক্ষ্ম অ্যাক্সেস নিয়ন্ত্রণের সুযোগ দেয়।

যখন কোনো প্রমাণীকৃত ব্যবহারকারী Cloud Storage বিরুদ্ধে কোনো অনুরোধ করেন, তখন request.auth ভেরিয়েবলটি ব্যবহারকারীর uid ( request.auth.uid ) এবং Firebase Authentication JWT-এর ক্লেইমগুলো ( 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 কাস্টম টোকেন তৈরি করুন, যাতে কোনো গ্রুপ সদস্যের অতিরিক্ত তথ্য (যেমন গ্রুপ আইডি) অন্তর্ভুক্ত থাকে।
  • ফাইলের মেটাডেটাতে গ্রুপের তথ্য (যেমন গ্রুপ আইডি বা অনুমোদিত 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;
}

মূল্যায়নের জন্য অনুরোধ করুন

Cloud Storage পাঠানো request ব্যবহার করে আপলোড, ডাউনলোড, মেটাডেটা পরিবর্তন এবং ডিলিট মূল্যায়ন করা হয়। উপরে বর্ণিত request.auth অবজেক্টে থাকা ব্যবহারকারীর অনন্য আইডি এবং Firebase Authentication পেলোড ছাড়াও, request ভেরিয়েবলটিতে সেই ফাইলের পাথ থাকে যেখানে অনুরোধটি করা হচ্ছে, অনুরোধটি প্রাপ্তির সময় এবং অনুরোধটি যদি রাইট হয় তবে নতুন resource ভ্যালুটি থাকে।

request অবজেক্টটিতে ` request.auth অবজেক্টের মধ্যে ব্যবহারকারীর ইউনিক আইডি এবং Firebase Authentication পেলোডও থাকে, যা ডক্সের 'ইউজার-বেসড সিকিউরিটি ' অংশে আরও বিস্তারিতভাবে ব্যাখ্যা করা হবে।

request অবজেক্টের প্রপার্টিগুলোর একটি সম্পূর্ণ তালিকা নিচে দেওয়া হলো:

সম্পত্তি প্রকার বর্ণনা
auth মানচিত্র<স্ট্রিং, স্ট্রিং> যখন কোনো ব্যবহারকারী লগ ইন করেন, তখন এটি uid (ব্যবহারকারীর অনন্য আইডি) এবং token ( Firebase Authentication JWT ক্লেইমগুলোর একটি ম্যাপ) প্রদান করে। অন্যথায়, এটি null হবে।
params মানচিত্র<স্ট্রিং, স্ট্রিং> অনুরোধের কোয়েরি প্যারামিটারগুলো ধারণকারী ম্যাপ।
path পথ একটি path যা সেই পথকে নির্দেশ করে যেখানে অনুরোধটি সম্পাদন করা হচ্ছে।
resource মানচিত্র<স্ট্রিং, স্ট্রিং> নতুন রিসোর্স মান, যা শুধুমাত্র write অনুরোধের ক্ষেত্রেই উপস্থিত থাকে।
time টাইমস্ট্যাম্প একটি টাইমস্ট্যাম্প যা সার্ভারের সেই সময়কে নির্দেশ করে, যে সময়ে অনুরোধটি মূল্যায়ন করা হয়।

সম্পদ মূল্যায়ন

নিয়মগুলো মূল্যায়ন করার সময়, আপনি আপলোড, ডাউনলোড, পরিবর্তন বা মুছে ফেলা ফাইলের মেটাডেটাও মূল্যায়ন করতে চাইতে পারেন। এটি আপনাকে জটিল ও শক্তিশালী নিয়ম তৈরি করার সুযোগ দেয়, যা দিয়ে শুধুমাত্র নির্দিষ্ট কন্টেন্ট টাইপের ফাইল আপলোড করার অনুমতি দেওয়া যায়, অথবা শুধুমাত্র একটি নির্দিষ্ট আকারের চেয়ে বড় ফাইল মুছে ফেলা যায়।

Cloud Storage জন্য Firebase Security Rules resource অবজেক্টে ফাইল মেটাডেটা প্রদান করে, যেখানে একটি Cloud Storage অবজেক্টে প্রদর্শিত মেটাডেটার কী/ভ্যালু পেয়ার থাকে। ডেটার অখণ্ডতা নিশ্চিত করার জন্য read বা write অনুরোধের সময় এই বৈশিষ্ট্যগুলি পরীক্ষা করা যেতে পারে।

write রিকোয়েস্টের (যেমন আপলোড, মেটাডেটা আপডেট এবং ডিলিট) ক্ষেত্রে, resource অবজেক্ট (যেটিতে রিকোয়েস্ট পাথে বর্তমানে বিদ্যমান ফাইলের মেটাডেটা থাকে) ছাড়াও, আপনার কাছে request.resource অবজেক্টে ফাইলের মেটাডেটার একটি উপসেট থাকে, যা লেখার অনুমতি থাকলে লেখা হবে। ডেটার অখণ্ডতা নিশ্চিত করতে অথবা ফাইলের ধরন বা আকারের মতো অ্যাপ্লিকেশনের সীমাবদ্ধতাগুলো প্রয়োগ করতে আপনি এই দুটি ভ্যালু ব্যবহার করতে পারেন।

resource অবজেক্টের প্রোপার্টিগুলোর একটি পূর্ণাঙ্গ তালিকা নিচে দেওয়া হলো:

সম্পত্তি প্রকার বর্ণনা
name স্ট্রিং বস্তুটির পুরো নাম
bucket স্ট্রিং যে বাকেটে এই অবজেক্টটি থাকে, তার নাম।
generation int এই অবজেক্টটির Google Cloud Storage অবজেক্ট জেনারেশন
metageneration int এই অবজেক্টটির Google Cloud Storage অবজেক্ট মেটাজেনারেশন
size int অবজেক্টটির আকার বাইটে।
timeCreated টাইমস্ট্যাম্প একটি টাইমস্ট্যাম্প যা কোনো অবজেক্ট তৈরি হওয়ার সময়কে নির্দেশ করে।
updated টাইমস্ট্যাম্প একটি টাইমস্ট্যাম্প যা কোনো অবজেক্টের সর্বশেষ আপডেটের সময় নির্দেশ করে।
md5Hash স্ট্রিং অবজেক্টটির একটি MD5 হ্যাশ।
crc32c স্ট্রিং অবজেক্টটির একটি crc32c হ্যাশ।
etag স্ট্রিং এই অবজেক্টের সাথে যুক্ত ই-ট্যাগ।
contentDisposition স্ট্রিং এই অবজেক্টের সাথে সম্পর্কিত বিষয়বস্তুর বিন্যাস।
contentEncoding স্ট্রিং এই অবজেক্টের সাথে সংশ্লিষ্ট কন্টেন্ট এনকোডিং।
contentLanguage স্ট্রিং এই অবজেক্টের সাথে সংশ্লিষ্ট বিষয়বস্তু ভাষা।
contentType স্ট্রিং এই অবজেক্টের সাথে সংশ্লিষ্ট কন্টেন্ট টাইপ।
metadata মানচিত্র<স্ট্রিং, স্ট্রিং> ডেভেলপার কর্তৃক নির্দিষ্ট অতিরিক্ত কাস্টম মেটাডেটার কী/ভ্যালু পেয়ার।

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 Storage Security Rules তৈরি এবং সেভ করলে, দুটি প্রোডাক্ট সংযোগ করার জন্য অনুমতি সক্রিয় করতে আপনাকে Firebase কনসোল বা Firebase সিএলআই-তে অনুরোধ করা হবে।

Firebase Security Rules পরিচালনা ও স্থাপন” অংশে বর্ণিত পদ্ধতি অনুযায়ী, একটি IAM রোল অপসারণ করে আপনি এই ফিচারটি নিষ্ক্রিয় করতে পারেন।

ডেটা যাচাই করুন

Cloud Storage জন্য Firebase Security Rules ডেটা যাচাইকরণের জন্যও ব্যবহার করা যেতে পারে, যার মধ্যে ফাইলের নাম এবং পাথের পাশাপাশি ফাইলের মেটাডেটা বৈশিষ্ট্য যেমন 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 আরও জটিল হয়ে উঠলে, আপনি শর্তাবলীর সেটগুলিকে এমন ফাংশনের মধ্যে রাখতে চাইতে পারেন যা আপনি আপনার রুলসেট জুড়ে পুনরায় ব্যবহার করতে পারবেন। সিকিউরিটি রুলস কাস্টম ফাংশন সমর্থন করে। কাস্টম ফাংশনের সিনট্যাক্স কিছুটা জাভাস্ক্রিপ্টের মতো, কিন্তু Firebase Security Rules ফাংশনগুলি একটি ডোমেইন-স্পেসিফিক ল্যাঙ্গুয়েজে লেখা হয় যার কিছু গুরুত্বপূর্ণ সীমাবদ্ধতা রয়েছে:

  • ফাংশনে শুধুমাত্র একটি return স্টেটমেন্ট থাকতে পারে। এতে কোনো অতিরিক্ত লজিক থাকতে পারে না। উদাহরণস্বরূপ, এটি লুপ চালাতে বা বাহ্যিক পরিষেবা কল করতে পারে না।
  • ফাংশনগুলো যে স্কোপে সংজ্ঞায়িত করা হয়, সেই স্কোপের ফাংশন এবং ভেরিয়েবল স্বয়ংক্রিয়ভাবে অ্যাক্সেস করতে পারে। উদাহরণস্বরূপ, service firebase.storage স্কোপের মধ্যে সংজ্ঞায়িত একটি ফাংশন resource ভেরিয়েবল এবং শুধুমাত্র Cloud Firestore জন্য get()exists() এর মতো বিল্ট-ইন ফাংশনগুলো অ্যাক্সেস করতে পারে।
  • ফাংশনগুলো একে অপরকে কল করতে পারে, কিন্তু পুনরাবৃত্তি (recurs) করতে পারে না। মোট কল স্ট্যাকের গভীরতা ১০-এ সীমাবদ্ধ।
  • ভার্সন rules2 এ, ফাংশনগুলো ` let কীওয়ার্ড ব্যবহার করে ভেরিয়েবল সংজ্ঞায়িত করতে পারে। ফাংশনে যেকোনো সংখ্যক `let` বাইন্ডিং থাকতে পারে, কিন্তু এর শেষে অবশ্যই একটি `return` স্টেটমেন্ট থাকতে হবে।

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 ফাংশন ব্যবহার করলে, নিয়মগুলির জটিলতা বাড়ার সাথে সাথে সেগুলিকে আরও সহজে রক্ষণাবেক্ষণ করা যায়।

পরবর্তী পদক্ষেপ

শর্তাবলী নিয়ে এই আলোচনার পর, আপনি নিয়মাবলী সম্পর্কে আরও উন্নত ধারণা লাভ করেছেন এবং নিম্নলিখিত বিষয়গুলোর জন্য প্রস্তুত:

কোর ইউজ কেসগুলো কীভাবে পরিচালনা করতে হয় তা শিখুন, এবং রুলস তৈরি, পরীক্ষা ও স্থাপন করার কর্মপ্রবাহ সম্পর্কে জানুন: