সিস্টেমের কিছু নির্দিষ্ট কাজ শুধু নির্দিষ্ট মানুষই করতে পারবে, এই পারমিশন লজিক হ্যান্ডেল করাই হলো RBAC। শুনতে খুব সহজ মনে হলেও, স্কেলেবল আর্কিটেকচারে এটি মেইনটেইন করা বেশ চ্যালেঞ্জিং।
ধরি, আমরা একটি এন্টারপ্রাইজ লেভেলের ই-কমার্স সিস্টেম বানাচ্ছি। শুরুতে আমাদের সিস্টেমে শুধু দুই ধরনের এক্সেস ছিল: User আর Admin। আমরা কন্ট্রোলারে খুব সহজেই লিখে ফেললাম: if (user.role === 'admin') { deleteProduct() }
সব ঠিকঠাকই কাজ করছিল। কিন্তু কয়েকদিন পর রিকোয়ারমেন্ট আসলো, আমাদের একজন Manager লাগবে যে প্রোডাক্ট আপডেট করতে পারবে কিন্তু ডিলিট করতে পারবে না। আবার একজন Support স্টাফ লাগবে যে শুধু রিড করতে পারবে। আমরা আবার কন্ট্রোলারে গিয়ে লিখলাম: if (role === 'admin' || role === 'manager') { editProduct() }
এভাবে প্রতিবার নতুন রোল আসার সাথে সাথে কন্ট্রোলারের ভেতর if-else এর চেইন বড় হতে থাকলে একসময় পুরো কোডবেস Spaghetti Code-এ পরিণত হবে। বিজনেস লজিক আর পারমিশন লজিক একসাথে মিলেমিশে একাকার হয়ে যাবে, যা মেইনটেইন করা অসম্ভব।
এর স্মার্ট সলিউশন হলো একটি ডাইনামিক Middleware Factory তৈরি করা। কন্ট্রোলারের ভেতরে আমরা পারমিশনের কোনো কোডই লিখবো না। আমরা রাউটারেই বলে দিবো এই এন্ডপয়েন্টে কারা ঢুকতে পারবে। ইউজারের রোল ম্যাচ না করলে কন্ট্রোলার রান হওয়ার আগেই 403 Forbidden রেসপন্স চলে যাবে।
// 1. The Dynamic Authorization Middleware exports.authorizeRoles = (...allowedRoles) => { return (req, res, next) => { // req.user is populated by previous JWT verification middleware if (!allowedRoles.includes(req.user.role)) { return res.status(403).json({ error: `Role: [${req.user.role}] is strictly prohibited from this action.` }); } next(); // Access Granted -> Move to Controller }; }; // 2. Clean, Declarative Routing router.route('/products/:id') // Anyone can read .get(getProduct) // Only Manager & Admin can update .put(verifyJWT, authorizeRoles('manager', 'admin'), updateProduct) // ONLY Admin can delete .delete(verifyJWT, authorizeRoles('admin'), deleteProduct);
নিচের ড্রপডাউন থেকে ইউজারের রোল পরিবর্তন করুন এবং বিভিন্ন অ্যাকশন বাটনে ক্লিক করে দেখুন Middleware কীভাবে পারমিশন হ্যান্ডেল করে। (লক্ষণীয়: আপনার বর্তমান রোলের ওপর ভিত্তি করে UI-তে লক আইকনও ডাইনামিকালি আপডেট হবে!)