ক্লাউড ফায়ারস্টোর নিরাপত্তা নিয়মের জন্য লেখার শর্ত

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

Cloud Firestore Security Rules প্রাথমিক বিল্ডিং ব্লক হল শর্ত। শর্ত হল একটি বুলিয়ান এক্সপ্রেশন যা নির্ধারণ করে যে কোনও নির্দিষ্ট ক্রিয়াকলাপ অনুমোদিত বা অস্বীকৃত হওয়া উচিত। ব্যবহারকারীর প্রমাণীকরণ পরীক্ষা করে, আগত ডেটা যাচাই করে, এমনকি আপনার ডাটাবেসের অন্যান্য অংশ অ্যাক্সেস করে এমন শর্তাবলী লিখতে সুরক্ষা নিয়ম ব্যবহার করুন।

প্রমাণীকরণ

ব্যবহারকারীর প্রমাণীকরণের অবস্থার উপর ভিত্তি করে অ্যাক্সেস নিয়ন্ত্রণ করা সবচেয়ে সাধারণ সুরক্ষা নিয়মের ধরণগুলির মধ্যে একটি। উদাহরণস্বরূপ, আপনার অ্যাপটি কেবল সাইন ইন করা ব্যবহারকারীদের ডেটা লেখার অনুমতি দিতে চাইতে পারে:

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow the user to access documents in the "cities" collection
    // only if they are authenticated.
    match /cities/{city} {
      allow read, write: if request.auth != null;
    }
  }
}

আরেকটি সাধারণ ধরণ হল ব্যবহারকারীরা কেবল তাদের নিজস্ব ডেটা পড়তে এবং লিখতে পারে তা নিশ্চিত করা:

service cloud.firestore {
  match /databases/{database}/documents {
    // Make sure the uid of the requesting user matches name of the user
    // document. The wildcard expression {userId} makes the userId variable
    // available in rules.
    match /users/{userId} {
      allow read, update, delete: if request.auth != null && request.auth.uid == userId;
      allow create: if request.auth != null;
    }
  }
}

যদি আপনার অ্যাপটি Firebase Authentication অথবা Google Cloud Identity Platform ব্যবহার করে, তাহলে request.auth ভেরিয়েবলে ক্লায়েন্টের ডেটা অনুরোধের প্রমাণীকরণ তথ্য থাকে। request.auth সম্পর্কে আরও তথ্যের জন্য, রেফারেন্স ডকুমেন্টেশন দেখুন।

ডেটা যাচাইকরণ

অনেক অ্যাপ ডাটাবেসের ডকুমেন্টের ফিল্ড হিসেবে অ্যাক্সেস নিয়ন্ত্রণ তথ্য সংরক্ষণ করে। Cloud Firestore Security Rules ডকুমেন্ট ডেটার উপর ভিত্তি করে গতিশীলভাবে অ্যাক্সেসের অনুমতি দিতে বা অস্বীকার করতে পারে:

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow the user to read data if the document has the 'visibility'
    // field set to 'public'
    match /cities/{city} {
      allow read: if resource.data.visibility == 'public';
    }
  }
}

resource ভেরিয়েবলটি অনুরোধকৃত ডকুমেন্টকে বোঝায় এবং resource.data হল ডকুমেন্টে সংরক্ষিত সমস্ত ক্ষেত্র এবং মানের একটি মানচিত্র। resource ভেরিয়েবল সম্পর্কে আরও তথ্যের জন্য, রেফারেন্স ডকুমেন্টেশন দেখুন।

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

service cloud.firestore {
  match /databases/{database}/documents {
    // Make sure all cities have a positive population and
    // the name is not changed
    match /cities/{city} {
      allow update: if request.resource.data.population > 0
                    && request.resource.data.name == resource.data.name;
    }
  }
}

অন্যান্য নথি অ্যাক্সেস করুন

get() এবং exists() ফাংশন ব্যবহার করে, আপনার নিরাপত্তা নিয়ম ডাটাবেসের অন্যান্য ডকুমেন্টের বিপরীতে ইনকামিং রিকোয়েস্ট মূল্যায়ন করতে পারে। get() এবং exists() ফাংশন উভয়ই সম্পূর্ণরূপে নির্দিষ্ট ডকুমেন্ট পাথ আশা করে। get() এবং exists() এর জন্য পাথ তৈরি করার জন্য ভেরিয়েবল ব্যবহার করার সময়, আপনাকে $(variable) সিনট্যাক্স ব্যবহার করে স্পষ্টভাবে ভেরিয়েবলগুলি এস্কেপ করতে হবে।

নিচের উদাহরণে, database ভেরিয়েবলটি match স্টেটমেন্ট match /databases/{database}/documents দ্বারা ক্যাপচার করা হয়েছে এবং পাথ তৈরি করতে ব্যবহৃত হয়েছে:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      // Make sure a 'users' document exists for the requesting user before
      // allowing any writes to the 'cities' collection
      allow create: if request.auth != null && exists(/databases/$(database)/documents/users/$(request.auth.uid));

      // Allow the user to delete cities if their user document has the
      // 'admin' field set to 'true'
      allow delete: if request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true;
    }
  }
}

লেখার ক্ষেত্রে, আপনি getAfter() ফাংশন ব্যবহার করে লেনদেন বা ব্যাচ লেখা সম্পূর্ণ হওয়ার পরে কিন্তু লেনদেন বা ব্যাচ তৈরি হওয়ার আগে ডকুমেন্টের অবস্থা জানতে পারেন। get() এর মতো, getAfter() ফাংশনটি সম্পূর্ণরূপে নির্দিষ্ট ডকুমেন্ট পাথ গ্রহণ করে। আপনি getAfter() ব্যবহার করে লেখার সেটগুলি সংজ্ঞায়িত করতে পারেন যা লেনদেন বা ব্যাচ হিসাবে একসাথে করা উচিত।

অ্যাক্সেস কল সীমা

নিয়ম সেট মূল্যায়নের জন্য ডকুমেন্ট অ্যাক্সেস কলের একটি সীমা রয়েছে:

  • একক-নথি অনুরোধ এবং কোয়েরি অনুরোধের জন্য ১০।
  • মাল্টি-ডকুমেন্ট রিড, লেনদেন এবং ব্যাচড রাইটসের জন্য ২০। পূর্ববর্তী ১০ এর সীমা প্রতিটি অপারেশনের ক্ষেত্রেও প্রযোজ্য।

    উদাহরণস্বরূপ, কল্পনা করুন আপনি 3টি লেখার অপারেশন সহ একটি ব্যাচড লেখার অনুরোধ তৈরি করেছেন এবং আপনার সুরক্ষা নিয়ম প্রতিটি লেখা যাচাই করার জন্য 2টি ডকুমেন্ট অ্যাক্সেস কল ব্যবহার করে। এই ক্ষেত্রে, প্রতিটি লেখা তার 10টি অ্যাক্সেস কলের মধ্যে 2টি ব্যবহার করে এবং ব্যাচড লেখার অনুরোধ তার 20টি অ্যাক্সেস কলের মধ্যে 6টি ব্যবহার করে।

যেকোনো সীমা অতিক্রম করলে অনুমতি অস্বীকারের ত্রুটি দেখা দেয়। কিছু ডকুমেন্ট অ্যাক্সেস কল ক্যাশে করা হতে পারে এবং ক্যাশে করা কলগুলি সীমার মধ্যে গণনা করা হয় না।

এই সীমাগুলি লেনদেন এবং ব্যাচড রাইটগুলিকে কীভাবে প্রভাবিত করে তার বিস্তারিত ব্যাখ্যার জন্য, পারমাণবিক ক্রিয়াকলাপ সুরক্ষিত করার নির্দেশিকাটি দেখুন।

কল এবং মূল্য অ্যাক্সেস করুন

এই ফাংশনগুলি ব্যবহার করলে আপনার ডাটাবেসে একটি পঠন অপারেশন কার্যকর হয়, যার অর্থ হল আপনার নিয়মগুলি অনুরোধ প্রত্যাখ্যান করলেও আপনাকে নথি পড়ার জন্য বিল করা হবে। আরও নির্দিষ্ট বিলিং তথ্যের জন্য Cloud Firestore মূল্য নির্ধারণ দেখুন।

কাস্টম ফাংশন

আপনার নিরাপত্তা নিয়মগুলি আরও জটিল হয়ে উঠার সাথে সাথে, আপনি আপনার নিয়ম সেট জুড়ে পুনরায় ব্যবহার করতে পারেন এমন ফাংশনগুলিতে শর্তগুলির সেটগুলি মোড়ানোর কথা ভাবতে পারেন। নিরাপত্তা নিয়মগুলি কাস্টম ফাংশনগুলিকে সমর্থন করে। কাস্টম ফাংশনগুলির সিনট্যাক্সটি কিছুটা জাভাস্ক্রিপ্টের মতো, তবে নিরাপত্তা নিয়ম ফাংশনগুলি একটি ডোমেন-নির্দিষ্ট ভাষায় লেখা হয় যার কিছু গুরুত্বপূর্ণ সীমাবদ্ধতা রয়েছে:

  • ফাংশনগুলিতে কেবল একটি return স্টেটমেন্ট থাকতে পারে। এতে কোনও অতিরিক্ত লজিক থাকতে পারে না। উদাহরণস্বরূপ, তারা লুপ এক্সিকিউট করতে বা বহিরাগত পরিষেবা কল করতে পারে না।
  • ফাংশনগুলি স্বয়ংক্রিয়ভাবে ফাংশন এবং ভেরিয়েবলগুলিকে সেই স্কোপে অ্যাক্সেস করতে পারে যেখানে সেগুলি সংজ্ঞায়িত করা হয়েছে। উদাহরণস্বরূপ, service cloud.firestore স্কোপের মধ্যে সংজ্ঞায়িত একটি ফাংশনের resource ভেরিয়েবল এবং get() এবং exists() এর মতো অন্তর্নির্মিত ফাংশনগুলিতে অ্যাক্সেস রয়েছে।
  • ফাংশনগুলি অন্যান্য ফাংশনগুলিকে কল করতে পারে কিন্তু পুনরাবৃত্তি নাও করতে পারে। মোট কল স্ট্যাকের গভীরতা 10 এর মধ্যে সীমাবদ্ধ।
  • rules ভার্সন v2 তে, ফাংশনগুলি let কীওয়ার্ড ব্যবহার করে ভেরিয়েবল সংজ্ঞায়িত করতে পারে। ফাংশনগুলিতে সর্বোচ্চ 10টি let বাইন্ডিং থাকতে পারে, তবে একটি রিটার্ন স্টেটমেন্ট দিয়ে শেষ হতে হবে।

একটি ফাংশন function কীওয়ার্ড দিয়ে সংজ্ঞায়িত করা হয় এবং শূন্য বা তার বেশি আর্গুমেন্ট লাগে। উদাহরণস্বরূপ, আপনি উপরের উদাহরণগুলিতে ব্যবহৃত দুটি ধরণের শর্তকে একটি একক ফাংশনে একত্রিত করতে চাইতে পারেন:

service cloud.firestore {
  match /databases/{database}/documents {
    // 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 /cities/{city} {
      allow read, write: if signedInOrPublic();
    }

    match /users/{user} {
      allow read, write: if signedInOrPublic();
    }
  }
}

আপনার নিরাপত্তা নিয়মে ফাংশন ব্যবহার করলে আপনার নিয়মের জটিলতা বৃদ্ধির সাথে সাথে এগুলি আরও রক্ষণাবেক্ষণযোগ্য হয়ে ওঠে।

নিয়মগুলি ফিল্টার নয়

একবার আপনি আপনার ডেটা সুরক্ষিত করে কোয়েরি লেখা শুরু করলে, মনে রাখবেন যে সুরক্ষা নিয়মগুলি ফিল্টার নয়। আপনি একটি সংগ্রহের সমস্ত নথির জন্য একটি কোয়েরি লিখতে পারবেন না এবং Cloud Firestore কেবলমাত্র সেই নথিগুলি ফেরত দেওয়ার আশা করতে পারবেন না যেগুলি বর্তমান ক্লায়েন্টের অ্যাক্সেসের অনুমতি রয়েছে।

উদাহরণস্বরূপ, নিম্নলিখিত নিরাপত্তা নিয়মটি ধরুন:

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow the user to read data if the document has the 'visibility'
    // field set to 'public'
    match /cities/{city} {
      allow read: if resource.data.visibility == 'public';
    }
  }
}

অস্বীকৃত : এই নিয়মটি নিম্নলিখিত কোয়েরিটি প্রত্যাখ্যান করে কারণ ফলাফল সেটে এমন নথি অন্তর্ভুক্ত থাকতে পারে যেখানে visibility public নয়:

ওয়েব
db.collection("cities").get()
    .then(function(querySnapshot) {
        querySnapshot.forEach(function(doc) {
            console.log(doc.id, " => ", doc.data());
    });
});

Allowed : এই নিয়মটি নিম্নলিখিত কোয়েরির অনুমতি দেয় কারণ where("visibility", "==", "public") ধারাটি গ্যারান্টি দেয় যে ফলাফল সেটটি নিয়মের শর্ত পূরণ করে:

ওয়েব
db.collection("cities").where("visibility", "==", "public").get()
    .then(function(querySnapshot) {
        querySnapshot.forEach(function(doc) {
            console.log(doc.id, " => ", doc.data());
        });
    });

Cloud Firestore নিরাপত্তা নিয়ম প্রতিটি প্রশ্নের সম্ভাব্য ফলাফলের সাথে মূল্যায়ন করে এবং যদি এটি এমন কোনও নথি ফেরত পাঠাতে পারে যা ক্লায়েন্টের পড়ার অনুমতি নেই তবে অনুরোধটি ব্যর্থ করে। প্রশ্নের অবশ্যই আপনার নিরাপত্তা নিয়ম দ্বারা নির্ধারিত সীমাবদ্ধতাগুলি অনুসরণ করতে হবে। নিরাপত্তা নিয়ম এবং প্রশ্নের আরও তথ্যের জন্য, নিরাপদে ডেটা অনুসন্ধান দেখুন।

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