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