ফায়ারবেস রিয়েলটাইম ডেটাবেস সিকিউরিটি রুলস আপনাকে আপনার ডেটাবেসে সংরক্ষিত ডেটার অ্যাক্সেস নিয়ন্ত্রণ করতে দেয়। এর নমনীয় রুলস সিনট্যাক্স আপনাকে এমন নিয়ম তৈরি করার সুযোগ দেয় যা আপনার ডেটাবেসে সমস্ত রাইট অপারেশন থেকে শুরু করে স্বতন্ত্র নোডের অপারেশন পর্যন্ত যেকোনো কিছুর সাথে মিল রাখে।
রিয়েলটাইম ডেটাবেস সিকিউরিটি রুলস হলো আপনার ডেটাবেসের জন্য ডিক্লারেটিভ কনফিগারেশন। এর মানে হলো, এই নিয়মগুলো প্রোডাক্ট লজিক থেকে আলাদাভাবে সংজ্ঞায়িত করা হয়। এর বেশ কিছু সুবিধা রয়েছে: ক্লায়েন্টদের নিরাপত্তা প্রয়োগের দায়িত্ব নিতে হয় না, ত্রুটিপূর্ণ বাস্তবায়ন আপনার ডেটার নিরাপত্তা বিঘ্নিত করবে না, এবং সম্ভবত সবচেয়ে গুরুত্বপূর্ণ হলো, ডেটাকে বাইরের জগৎ থেকে রক্ষা করার জন্য সার্ভারের মতো কোনো মধ্যবর্তী রেফারির প্রয়োজন হয় না।
এই টপিকে সম্পূর্ণ রুলসেট তৈরি করতে ব্যবহৃত রিয়েলটাইম ডেটাবেস সিকিউরিটি রুলসের মৌলিক সিনট্যাক্স এবং কাঠামো বর্ণনা করা হয়েছে।
আপনার নিরাপত্তা নিয়মাবলীর কাঠামো তৈরি করা
রিয়েলটাইম ডেটাবেস সিকিউরিটি রুলগুলো একটি JSON ডকুমেন্টের মধ্যে থাকা জাভাস্ক্রিপ্ট-সদৃশ এক্সপ্রেশন দিয়ে গঠিত। আপনার রুলগুলোর কাঠামো আপনার ডেটাবেসে সংরক্ষিত ডেটার কাঠামো অনুসরণ করবে।
মৌলিক নিয়মগুলো সুরক্ষিত করার জন্য নোডগুলোর একটি সেট , সংশ্লিষ্ট অ্যাক্সেস পদ্ধতি (যেমন, পড়া, লেখা), এবং যে শর্তগুলোর অধীনে অ্যাক্সেস অনুমোদিত বা প্রত্যাখ্যাত হয়, তা চিহ্নিত করে। নিম্নলিখিত উদাহরণগুলোতে, আমাদের শর্তগুলো হবে সাধারণ true এবং false বিবৃতি, কিন্তু পরবর্তী বিষয়ে আমরা শর্ত প্রকাশের আরও গতিশীল উপায় নিয়ে আলোচনা করব।
সুতরাং, উদাহরণস্বরূপ, যদি আমরা একটি parent_node অধীনে একটি child_node সুরক্ষিত করতে চাই, তাহলে অনুসরণ করার সাধারণ সিনট্যাক্সটি হলো:
{
"rules": {
"parent_node": {
"child_node": {
".read": <condition>,
".write": <condition>,
".validate": <condition>,
}
}
}
}চলুন এই প্যাটার্নটি প্রয়োগ করি। উদাহরণস্বরূপ, ধরা যাক আপনি মেসেজের একটি তালিকা রাখছেন এবং আপনার কাছে থাকা ডেটা দেখতে এইরকম:
{
"messages": {
"message0": {
"content": "Hello",
"timestamp": 1405704370369
},
"message1": {
"content": "Goodbye",
"timestamp": 1405704395231
},
...
}
}আপনার নিয়মগুলোও একইভাবে সাজানো উচিত। এখানে রিড-অনলি সিকিউরিটির জন্য কিছু নিয়ম দেওয়া হলো যা এই ডেটা স্ট্রাকচারের জন্য উপযুক্ত হতে পারে। এই উদাহরণটি দেখায় যে, আমরা কীভাবে ডাটাবেস নোডগুলো নির্দিষ্ট করি যেখানে নিয়মগুলো প্রযোজ্য হবে এবং সেই নোডগুলোতে নিয়মগুলো মূল্যায়নের শর্তগুলোও নির্দিষ্ট করি।
{ "rules": { // For requests to access the 'messages' node... "messages": { // ...and the individual wildcarded 'message' nodes beneath // (we'll cover wildcarding variables more a bit later).... "$message": { // For each message, allow a read operation if <condition>. In this // case, we specify our condition as "true", so read access is always granted. ".read": "true", // For read-only behavior, we specify that for write operations, our // condition is false. ".write": "false" } } } }
মৌলিক নিয়মাবলী কার্যক্রম
ডেটার উপর সম্পাদিত অপারেশনের ধরনের উপর ভিত্তি করে নিরাপত্তা জোরদার করার জন্য তিন ধরনের নিয়ম রয়েছে: .write , .read , এবং .validate । নিচে এগুলোর উদ্দেশ্যের একটি সংক্ষিপ্ত বিবরণ দেওয়া হলো:
| নিয়মের প্রকারভেদ | |
|---|---|
| পড়া | ব্যবহারকারীরা কখন এবং কীভাবে ডেটা পড়তে পারবে, তা বর্ণনা করে। |
| লিখুন | ডেটা লেখার অনুমতি আছে কি না এবং কখন আছে, তা বর্ণনা করে। |
| যাচাই করুন | একটি সঠিকভাবে ফরম্যাট করা মান দেখতে কেমন হবে, তার চাইল্ড অ্যাট্রিবিউট থাকবে কিনা এবং তার ডেটা টাইপ কী হবে, তা নির্ধারণ করে। |
ওয়াইল্ডকার্ড ক্যাপচার ভেরিয়েবল
সমস্ত রুলস স্টেটমেন্ট নোডকে নির্দেশ করে। একটি স্টেটমেন্ট একটি নির্দিষ্ট নোডকে নির্দেশ করতে পারে অথবা হায়ারার্কির কোনো একটি স্তরে নোডের সেটকে নির্দেশ করার জন্য $ ওয়াইল্ডকার্ড ক্যাপচার ভেরিয়েবল ব্যবহার করতে পারে। পরবর্তী রুলস স্টেটমেন্টের ভিতরে ব্যবহারের জন্য নোড কী-এর মান সংরক্ষণ করতে এই ক্যাপচার ভেরিয়েবলগুলো ব্যবহার করুন। এই কৌশলটি আপনাকে আরও জটিল Security Rules কন্ডিশন লিখতে সাহায্য করে, যা আমরা পরবর্তী টপিকে আরও বিস্তারিতভাবে আলোচনা করব।
{ "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')" } } } } }
ডাইনামিক $ ভেরিয়েবলগুলো কনস্ট্যান্ট পাথ নেমের সাথেও সমান্তরালভাবে ব্যবহার করা যায়। এই উদাহরণে, আমরা $other ভেরিয়েবলটি ব্যবহার করে একটি .validate রুল ডিক্লেয়ার করছি, যা নিশ্চিত করে যে widget title এবং color ছাড়া অন্য কোনো চাইল্ড নেই। এমন যেকোনো রাইট অপারেশন যা অতিরিক্ত চাইল্ড তৈরি করবে, তা ফেইল করবে।
{
"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 }
}
}
}পঠন ও লিখন নিয়মের ক্রমবিকাশ
.read এবং .write নিয়মগুলো উপর থেকে নিচে কাজ করে, যেখানে নিচের দিকের নিয়মগুলো নিচের দিকের নিয়মগুলোকে বাতিল করে দেয়। যদি কোনো নিয়ম একটি নির্দিষ্ট পাথে পড়া বা লেখার অনুমতি দেয়, তবে এটি তার অধীনস্থ সমস্ত চাইল্ড নোডেও অ্যাক্সেসের অনুমতি দেয়। নিম্নলিখিত কাঠামোটি বিবেচনা করুন:
{
"rules": {
"foo": {
// allows read to /foo/*
".read": "data.child('baz').val() === true",
"bar": {
/* ignored, since read was allowed already */
".read": false
}
}
}
} এই নিরাপত্তা কাঠামোটি /bar/ থেকে পড়ার অনুমতি দেয় যখনই /foo/ তে true মানের একটি চাইল্ড ' baz থাকে। /foo/bar/ এর অধীনে থাকা ".read": false নিয়মটি এখানে কার্যকর নয়, কারণ একটি চাইল্ড পাথ দ্বারা অ্যাক্সেস প্রত্যাহার করা যায় না।
যদিও এটি তাৎক্ষণিকভাবে স্বজ্ঞাত নাও মনে হতে পারে, এটি রুলস ল্যাঙ্গুয়েজের একটি শক্তিশালী অংশ এবং এর মাধ্যমে ন্যূনতম প্রচেষ্টায় অত্যন্ত জটিল অ্যাক্সেস প্রিভিলেজ প্রয়োগ করা যায়। এই গাইডের পরবর্তী অংশে যখন আমরা ইউজার-ভিত্তিক নিরাপত্তা নিয়ে আলোচনা করব, তখন বিষয়টি ব্যাখ্যা করা হবে।
মনে রাখবেন যে .validate নিয়মগুলো ক্রমান্বয়ে কাজ করে না। কোনো রাইট অনুমোদিত হওয়ার জন্য হায়ারার্কির সকল স্তরে সমস্ত validate নিয়ম অবশ্যই পূরণ করতে হবে।
নিয়ম ফিল্টার নয়
নিয়মগুলো অ্যাটমিক পদ্ধতিতে প্রয়োগ করা হয়। এর মানে হলো, যদি কোনো নির্দিষ্ট স্থানে বা তার প্যারেন্ট লোকেশনে অ্যাক্সেস দেওয়ার মতো কোনো নিয়ম না থাকে, তাহলে রিড বা রাইট অপারেশনটি সঙ্গে সঙ্গে ব্যর্থ হয়ে যায়। এমনকি যদি প্রতিটি অ্যাফেক্টেড চাইল্ড পাথ অ্যাক্সেসযোগ্যও হয়, প্যারেন্ট লোকেশনে রিড করার চেষ্টা পুরোপুরি ব্যর্থ হবে। এই কাঠামোটি বিবেচনা করুন:
{
"rules": {
"records": {
"rec1": {
".read": true
},
"rec2": {
".read": false
}
}
}
} নিয়মগুলো যে অ্যাটমিকভাবে মূল্যায়ন করা হয়, তা না বুঝলে মনে হতে পারে যে /records/ পাথটি ফেচ করলে rec1 রিটার্ন হবে কিন্তু rec2 হবে না। তবে, প্রকৃত ফলাফলটি হলো একটি এরর:
জাভাস্ক্রিপ্ট
var db = firebase.database(); db.ref("records").once("value", function(snap) { // success method is not called }, function(err) { // error callback triggered with PERMISSION_DENIED });
উদ্দেশ্য-সি
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 }];
সুইফট
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 })
জাভা
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 }); });
বিশ্রাম
curl https://docs-examples.firebaseio.com/rest/records/ # response returns a PERMISSION_DENIED error
যেহেতু /records/ এ রিড অপারেশনটি অ্যাটমিক, এবং /records/ অধীনে থাকা সমস্ত ডেটাতে অ্যাক্সেস দেওয়ার মতো কোনো রিড রুল নেই, তাই এটি একটি PERMISSION_DENIED এরর দেবে। যদি আমরা আমাদের Firebase কনসোলের সিকিউরিটি সিমুলেটরে এই রুলটি ইভ্যালুয়েট করি, আমরা দেখতে পাব যে রিড অপারেশনটি ডিনাই করা হয়েছে কারণ কোনো রিড রুলই /records/ পাথে অ্যাক্সেসের অনুমতি দেয়নি। তবে, লক্ষ্য করুন যে rec1 এর জন্য রুলটি কখনোই ইভ্যালুয়েট করা হয়নি কারণ এটি আমাদের অনুরোধ করা পাথে ছিল না। rec1 ফেচ করার জন্য, আমাদের এটিকে সরাসরি অ্যাক্সেস করতে হবে:
জাভাস্ক্রিপ্ট
var db = firebase.database(); db.ref("records/rec1").once("value", function(snap) { // SUCCESS! }, function(err) { // error callback is not called });
উদ্দেশ্য-সি
FIRDatabaseReference *ref = [[FIRDatabase database] reference]; [[ref child:@"records/rec1"] observeSingleEventOfType:FEventTypeValue withBlock:^(FIRDataSnapshot *snapshot) { // SUCCESS! }];
সুইফট
var ref = FIRDatabase.database().reference() ref.child("records/rec1").observeSingleEventOfType(.Value, withBlock: { snapshot in // SUCCESS! })
জাভা
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 } });
বিশ্রাম
curl https://docs-examples.firebaseio.com/rest/records/rec1 # SUCCESS!
পরস্পর-ব্যাপ্ত বিবৃতি
একটি নোডের ক্ষেত্রে একাধিক নিয়ম প্রযোজ্য হতে পারে। যদি একাধিক নিয়ম এক্সপ্রেশন একটি নোডকে শনাক্ত করে, তবে শর্তগুলোর কোনো একটি false হলে অ্যাক্সেস পদ্ধতিটি প্রত্যাখ্যাত হয়।
{
"rules": {
"messages": {
// A rule expression that applies to all nodes in the 'messages' node
"$message": {
".read": "true",
".write": "true"
},
// A second rule expression applying specifically to the 'message1` node
"message1": {
".read": "false",
".write": "false"
}
}
}
}উপরের উদাহরণে, message1 নোডে রিড করার অনুরোধ প্রত্যাখ্যান করা হবে, কারণ দ্বিতীয় নিয়মটি সর্বদা false , যদিও প্রথম নিয়মটি সর্বদা true ।
পরবর্তী পদক্ষেপ
আপনি ফায়ারবেস রিয়েলটাইম ডেটাবেস নিরাপত্তা নিয়মাবলী সম্পর্কে আপনার জ্ঞান আরও গভীর করতে পারেন:
Security Rules ল্যাঙ্গুয়েজের পরবর্তী প্রধান ধারণা, ডাইনামিক কন্ডিশনস সম্পর্কে জানুন, যা আপনার Security Rules ব্যবহারকারীর অনুমোদন যাচাই করতে, বিদ্যমান ও আগত ডেটার তুলনা করতে, আগত ডেটা যাচাই করতে, ক্লায়েন্ট থেকে আসা কোয়েরির কাঠামো পরীক্ষা করতে এবং আরও অনেক কিছু করতে সাহায্য করে।
সাধারণ নিরাপত্তা ব্যবহারের ক্ষেত্রসমূহ এবং সেগুলোকে সমাধানকারী Firebase নিরাপত্তা নিয়মের সংজ্ঞাগুলো পর্যালোচনা করুন।