Firebase এর হাতেখড়ি (পর্ব ৮) – Security Rules গভীরভাবে

Firebase Realtime Database Security Rules

পর্ব ৫-এ একটা সতর্কতা দিয়েছিলাম — Test mode-এ ডিফল্ট Rules হয় ".read": true, ".write": true, অর্থাৎ পৃথিবীর যে কেউ আপনার ডেটাবেজ পড়তে বা মুছে ফেলতে পারবে। আজ আমরা সেই ফাঁকটা বন্ধ করব — Security Rules দিয়ে ঠিক করব কে কী পড়তে/লিখতে পারবে।

Security Rules কোথায় লিখবেন

Firebase Console-এ Realtime Database → Rules ট্যাবে গেলে একটা JSON-এর মতো এডিটর পাওয়া যায়। এখানে Rules লিখে Publish চাপলেই সাথে সাথে কার্যকর হয়ে যায় — কোনো ডেপ্লয়মেন্ট লাগে না।

সবচেয়ে বিপজ্জনক — Test Mode Rules

// ❌ কখনো প্রোডাকশনে না — যে কেউ সব দেখতে/মুছতে পারবে
{
  "rules": {
    ".read": true,
    ".write": true
  }
}

ধাপ ১ — শুধু লগইন করা ইউজার

সবচেয়ে সাধারণ প্রথম ধাপ — শুধু লগইন করা ইউজারই পড়তে/লিখতে পারবে, বাকিদের জন্য বন্ধ।

{
  "rules": {
    ".read": "auth != null",
    ".write": "auth != null"
  }
}

এখানে auth একটা বিল্ট-ইন ভ্যারিয়েবল — যদি ইউজার Firebase Authentication দিয়ে লগইন করা থাকে (পর্ব ৩-এর onAuthStateChanged মনে আছে?), তাহলে এটা তার তথ্য ধারণ করে; না হলে null থাকে।

ধাপ ২ — নোড-ভিত্তিক নিয়ম

পুরো ডেটাবেজে একই নিয়ম না দিয়ে, প্রতিটা নোডের জন্য আলাদা নিয়ম লেখা যায় — এটাই বাস্তব প্রজেক্টে বেশি ব্যবহৃত হয়।

{
  "rules": {
    "books": {
      ".read": true,
      ".write": "auth != null"
    },
    "users": {
      "$uid": {
        ".read": "auth != null && auth.uid == $uid",
        ".write": "auth != null && auth.uid == $uid"
      }
    }
  }
}

এখানে দুইটা গুরুত্বপূর্ণ প্যাটার্ন —

  • books — সবাই পড়তে পারবে (পাবলিক বই তালিকা), কিন্তু লিখতে হলে লগইন লাগবে
  • users/$uid$uid একটা wildcard variable, যেকোনো চাইল্ড কী-কে ধরে। শর্তটা বলছে — ইউজার শুধু নিজের ডেটা (auth.uid == $uid) পড়তে/লিখতে পারবে, অন্য কারো প্রোফাইল না

.validate — ডেটার গঠন যাচাই করা

শুধু কে লিখতে পারবে তা না, কী ধরনের ডেটা লেখা যাবে তাও নিয়ন্ত্রণ করা যায় — .validate দিয়ে।

{
  "rules": {
    "books": {
      "$bookId": {
        ".read": true,
        ".write": "auth != null",
        "title": {
          ".validate": "newData.isString() && newData.val().length > 0"
        },
        "year": {
          ".validate": "newData.isNumber() && newData.val() > 1800"
        }
      }
    }
  }
}

এই নিয়মে title খালি স্ট্রিং হতে পারবে না, আর year অবশ্যই ১৮০০-এর পরের একটা সংখ্যা হতে হবে — এভাবে ফ্রন্টএন্ড থেকে ভুল বা ক্ষতিকর ডেটা এলেও ডেটাবেজ পর্যায়ে সেটা আটকানো যায়।

.indexOn — Query দ্রুত করা

পর্ব ৭-এ orderByChild("author") ব্যবহার করেছিলাম। বড় ডেটাসেটে এই query দ্রুত করতে Rules-এ ইনডেক্স যোগ করতে হয়।

{
  "rules": {
    "books": {
      ".read": true,
      ".write": "auth != null",
      ".indexOn": ["author", "year"]
    }
  }
}

সবগুলো একসাথে — একটা বাস্তব উদাহরণ

ধরা যাক একটা বুক-শেয়ারিং অ্যাপ, যেখানে সবাই বই দেখতে পারবে, শুধু লগইন করা ইউজার নতুন বই যোগ করতে পারবে, আর একজন ইউজার শুধু নিজের যোগ করা বই এডিট/ডিলিট করতে পারবে।

{
  "rules": {
    "books": {
      ".read": true,
      ".indexOn": ["author", "year"],
      "$bookId": {
        ".write": "auth != null && (!data.exists() || data.child('ownerId').val() == auth.uid)",
        "title": { ".validate": "newData.isString() && newData.val().length > 0" },
        "ownerId": { ".validate": "newData.val() == auth.uid" }
      }
    }
  }
}

এখানে !data.exists() মানে — এটা একটা নতুন বই (তাই যে কেউ লগইন থাকলে যোগ করতে পারবে), আর data.child('ownerId').val() == auth.uid মানে — আগে থেকে থাকা বই হলে শুধু owner-ই এডিট করতে পারবে।

ইন্টারেক্টিভ — Rules Simulator

নিচে বিভিন্ন পরিস্থিতিতে Rules কী সিদ্ধান্ত নেবে তা টেস্ট করে দেখো — ঠিক যেমন Firebase Console-এর Rules Playground কাজ করে।

চেকবক্স বদলে বদলে দেখো কীভাবে auth != null আর ownerId ম্যাচ শর্ত দুটো ফলাফল বদলে দেয়।

ভালো অভ্যাস

  • Test mode কখনো লাইভ রাখবেন না — Console-এ ৩০ দিন পর এমনিতেই বন্ধ হয়ে যায়, কিন্তু নিজে থেকে আগেই বদলে ফেলা উচিত
  • Rules-এ ক্লায়েন্ট-সাইড ভ্যালিডেশনের ওপর ভরসা করবেন না — ব্রাউজার DevTools দিয়ে যেকোনো JS বাইপাস করা যায়, তাই আসল নিরাপত্তা সবসময় Rules-এ থাকতে হবে
  • Console-এর Rules Playground ব্যবহার করুন — Publish করার আগে বিভিন্ন সিনারিও টেস্ট করে নেওয়া যায়

নিজে চেষ্টা করো

Exercise:

  1. নিজের প্রজেক্টে Rules বদলে "auth != null" বসাও, তারপর লগআউট অবস্থায় ডেটা পড়ার চেষ্টা করে দেখো কী error আসে।
  2. নিজের users/$uid প্যাটার্ন লিখে টেস্ট করো — অন্য ইউজারের UID দিয়ে ডেটা পড়ার চেষ্টা করে দেখো Rules আটকায় কিনা।
  3. একটা .validate রুল লিখে দেখো খালি টাইটেল দিয়ে বই যোগ করার চেষ্টা করলে Firebase কীভাবে প্রত্যাখ্যান করে।
  4. Console-এর Rules Playground-এ গিয়ে উপরের বুক-শেয়ারিং উদাহরণটা নিজে টেস্ট করো।

পরের পর্বে যা থাকছে

পরের পর্বে আমরা শিখব Firebase Storage — ছবি ও ফাইল আপলোড, ডাউনলোড লিংক তৈরি, আর Storage-এর নিজস্ব Security Rules কীভাবে লিখতে হয়।

একটি মন্তব্য পোস্ট করুন

নবীনতর পূর্বতন

যোগাযোগ ফর্ম