Vue 3 রাউট গার্ড: রোল-ভিত্তিক অ্যাক্সেসের ব্যবহারিক প্যাটার্ন
Vue 3 রাউট গার্ডস দিয়ে রোল-ভিত্তিক অ্যাক্সেস ব্যাখ্যা করা: রুট meta নিয়ম, নিরাপদ রিডিরেক্ট, বন্ধুত্বপূর্ণ 401/403 ফলব্যাক, এবং ডেটা লিক এড়ানো।

কোন সমস্যাগুলো রাউট গার্ড আসলেই সমাধান করে (এবং কি না)
রাউট গার্ড এক কাজ ভালো করে: নেভিগেশন নিয়ন্ত্রণ করা। তারা নির্ধারণ করে কেউ একটি রুটে প্রবেশ করতে পারবে কি না, এবং যদি না পারে তবে তাকে কোথায় পাঠানো হবে। এটি UX উন্নত করে, কিন্তু এটা নিরাপত্তার সমান নয়।
মেনু আইটেম লুকানো কেবল এক ইঙ্গিত; তা অনুমোদন নয়। মানুষ এখনও URL টাইপ করতে পারে, একটি ডিপ লিংকে রিফ্রেশ করতে পারে, বা বুকমার্ক খুলতে পারে। আপনার একমাত্র নিরাপত্তা যদি “বাটন দেখা যাচ্ছে না” হয়, তাহলে কোনো রক্ষা নেই।
গার্ড ভালো কাজ করে যখন আপনি চান অ্যাপ ধারাবাহিকভাবে আচরণ করুক এবং এমন পেজগুলো ব্লক করুক যেগুলো দেখানো উচিত নয়—যেমন অ্যাডমিন এরিয়া, অভ্যন্তরীণ টুল, বা রোল-ভিত্তিক কাস্টমার পোর্টাল।
গার্ড আপনাকে সাহায্য করে:
- পেজগুলো রেন্ডার হওয়ার আগে ব্লক করতে
- লগইন বা একটি নিরাপদ ডিফল্টে রিডিরেক্ট করতে
- ভাঙা ভিউয়ের বদলে পরিষ্কার 401/403 দেখাতে
- আকস্মিক নেভিগেশন লুপ এড়াতে
যা গার্ড করতে পারে না তা হল একা ডেটা রক্ষা করা। যদি API ব্রাউজারে সংবেদনশীল ডেটা ফেরত দেয়, ব্যবহারকারী তখনও সরাসরি সেই এন্ডপয়েন্ট কল করতে পারে (বা dev tools-এ রেসপন্স দেখতে পারে) যদিও পেজ ব্লক করা আছে। বাস্তব অনুমোদন সার্ভারেও ঘটতে হবে।
ভালো লক্ষ্য হল উভয় দিক কভার করা: পেজ ব্লক করা এবং ডেটা ব্লক করা। যদি একটি সাপোর্ট এজেন্ট একটি অ্যাডমিন-শুধু রুট খোলে, গার্ড নেভিগেশন বন্ধ করে এবং “Access denied” দেখানো উচিত। আলাদা করে, আপনার ব্যাকএন্ডকে অ্যাডমিন-শুধু API কলগুলো প্রত্যাখ্যান করতে হবে, যাতে সীমিত ডেটা কখনই ফেরত না আসে।
একটি সহজ রোল ও পারমিশন মডেল বেছে নিন
অ্যাক্সেস কন্ট্রোল জটিল হয়ে যায় যখন আপনি অনেক রোল দিয়ে শুরু করেন। ছোট একটি সেট দিয়ে শুরু করুন যা সবাই বুঝে, তারপর বাস্তব সমস্যায় পড়লে সূক্ষ্ম পারমিশন যোগ করুন।
একটি ব্যবহারিক বিভাজন হলো:
- রোল বর্ণনা করে কেউ আপনার অ্যাপে কে।
- পারমিশন বর্ণনা করে তারা কী করতে পারে।
অধিকাংশ অভ্যন্তরীণ টুলের জন্য তিনটি রোল অনেক ক্ষেত্রেই চলবে:
- admin: ইউজার ও সেটিংস ম্যানেজ করা, সব ডেটা দেখা
- support: কাস্টমার রেকর্ড এবং উত্তর পরিচালনা করা, কিন্তু সিস্টেম সেটিংস নয়
- viewer: অনুমোদিত স্ক্রিনগুলোতে কেবল-পঠিত অ্যাক্সেস
শুরুতেই ঠিক করুন রোল কোথা থেকে আসে। টোকেন ক্লেইমস (JWT) গার্ডের জন্য দ্রুত, কিন্তু রিফ্রেশ না করা পর্যন্ত তারা পুরনো হতে পারে। অ্যাপ শুরুতে ইউজার প্রোফাইল ফেচ করা সর্বদা আপ-টু-ডেট, কিন্তু তখন আপনার গার্ডগুলোকে সেই রিকোয়েস্ট শেষ হওয়া পর্যন্ত অপেক্ষা করতে হবে।
এছাড়াও আপনার রুট টাইপগুলো পরিষ্কারভাবে আলাদা করুন: পাবলিক রুট (সবাই জন্য খোলা), প্রমাণীকৃত রুট (সেশন দরকার), এবং সীমাবদ্ধ রুট (রোল বা পারমিশন দরকার)।
রুট meta দিয়ে অ্যাক্সেস রুল নির্ধারণ করুন
সবচেয়ে পরিষ্কার উপায় হল রুটেই অ্যাক্সেস ঘোষণা করা। Vue Router আপনাকে প্রতিটি রুট রেকর্ডে একটি meta অবজেক্ট লাগাতে দেয় যাতে আপনার গার্ড পরে তা পড়তে পারে। এতে রুলগুলো সেই পেজের কাছাকাছি থাকে যা তারা রক্ষা করে।
একটি সহজ meta আকার বেছে নিন এবং পুরো অ্যাপে স্থিরভাবে ব্যবহার করুন।
const routes = [
{
path: "/admin",
component: () => import("@/pages/AdminLayout.vue"),
meta: { requiresAuth: true, roles: ["admin"] },
children: [
{
path: "users",
component: () => import("@/pages/AdminUsers.vue"),
// inherits requiresAuth + roles from parent
},
{
path: "audit",
component: () => import("@/pages/AdminAudit.vue"),
meta: { permissions: ["audit:read"] },
},
],
},
{
path: "/tickets",
component: () => import("@/pages/Tickets.vue"),
meta: { requiresAuth: true, permissions: ["tickets:read"], readOnly: true },
},
]
নেস্টেড রুটগুলোর জন্য ঠিক করুন রুলগুলো কিভাবে মিলবে। বেশিরভাগ অ্যাপে, চাইল্ডরা প্যারেন্ট requirements উত্তরাধিকার সূত্রে পাবে। আপনার গার্ডে প্রতিটি matched route record চেক করুন (শুধুমাত্র to.meta নয়) যাতে প্যারেন্ট রুলগুলো বাদ না পড়ে।
একটি ছোট বিবরণ যা পরে সময় বাঁচায়: “দেখতে পারা” এবং “সম্পাদন করতে পারা” আলাদা করুন। একটি রুট support ও admin উভয়ের জন্য দৃশ্যমান হতে পারে, কিন্তু support-দের জন্য এডিটগুলি নিষ্ক্রিয় থাকা উচিত। একটি readOnly: true ফ্ল্যাগ UI-ব্যবহারকে (অ্যাকশন ডিসেবল করা, ধ্বংসাত্মক বাটন লুকানো) চালাতে পারে, কিন্তু এটা নিরাপত্তা বলার চেহারা করবে না।
গার্ডগুলো নির্ভরযোগ্যভাবে কাজ করুক এমন auth স্টেট প্রস্তুত করুন
বেশিরভাগ গার্ড বাগই আসে এক সমস্যার কারণে: গার্ড চালানো হয় অ্যাপ তখনও জানে না ইউজার কে।
auth-কে একটি ছোট স্টেট মেশিন হিসেবে বিবেচনা করুন এবং এটিকে একক সত্যের সূত্র বানান। আপনাকে তিনটি স্পষ্ট স্টেট দরকার:
- unknown: অ্যাপ ঠিকই শুরু হয়েছে, সেশন এখনও চেক হয়নি
- logged out: সেশন চেক শেষ, কোন বৈধ ইউজার নেই
- logged in: ইউজার লোড হয়েছে, রোল/পারমিশন উপস্থিত
নিয়ম: auth unknown অবস্থায় কখনই রোল পড়বেন না। এভাবেই আপনি সুরক্ষিত স্ক্রিনের ফ্ল্যাশ বা অপ্রত্যাশিত রিডিরেক্ট পাবেন না।
সেশনের রিফ্রেশ কিভাবে কাজ করবে তা ঠিক করুন
একটি রিফ্রেশ কৌশল বেছে নিন এবং তা পূর্বানুমিতভাবে রাখুন (উদাহরণ: টোকেন পড়া, একটি “who am I” এন্ডপয়েন্ট কল করা, ইউজার সেট করা)।
একটি স্থিতিশীল প্যাটার্ন দেখতে পারে এমন:
- অ্যাপ লোডে, auth-কে unknown সেট করুন এবং একটি একক রিফ্রেশ রিকোয়েস্ট শুরু করুন
- রিফ্রেশ শেষ হওয়া (বা টাইমআউট) না হওয়া পর্যন্ত গার্ডগুলো রিজল্ভ করবেন না
- ইউজার মেমরি-এ কেচ করুন, route meta-তে নয়
- ব্যর্থ হলে auth-কে logged out setzen করুন
- একটি
readyপ্রমিস (বা অনুরূপ) প্রকাশ করুন যাতে গার্ডগুলো await করতে পারে
একবার এটি স্থাপন হলে, গার্ড লজিক সোজা থাকে: auth ready হওয়া পর্যন্ত অপেক্ষা করুন, তারপর অ্যাক্সেস নির্ধারণ করুন।
ধাপে ধাপে: রুট-লেভেল অথোরাইজেশন বাস্তবায়ন
একটি পরিষ্কার পদ্ধতি হলো বেশিরভাগ রুল একটি গ্লোবাল গার্ডে রাখা, এবং শুধুমাত্র তখনই per-route গার্ড ব্যবহার করা যখন রুট সত্যিই বিশেষ লজিক চায়।
1) একটি গ্লোবাল beforeEach গার্ড যোগ করুন
// router/index.js
router.beforeEach(async (to) => {
const auth = useAuthStore()
// Step 2: wait for auth initialization when needed
if (!auth.ready) await auth.init()
// Step 3: check authentication, then roles/permissions
if (to.meta.requiresAuth && !auth.isAuthenticated) {
return { name: 'login', query: { redirect: to.fullPath } }
}
const roles = to.meta.roles
if (roles && roles.length > 0 && !roles.includes(auth.userRole)) {
return { name: 'forbidden' } // 403
}
// Step 4: allow navigation
return true
})
এটি বেশিরভাগ কেস কভার করে בלי চেকগুলো কম্পোনেন্টের মধ্যে ছড়িয়ে দিতে।
কখন beforeEnter ভাল ফিট
beforeEnter তখন ব্যবহার করুন যখন রুল সত্যিই route-specific, যেমন “শুধু টিকিটের মালিক এই পেজ খুলতে পারে” এবং এটা to.params.id-এর উপর নির্ভর করে। ছোট রাখুন এবং একই auth store reuse করুন যাতে আচরণ স্থির থাকে।
নিরাপদ রিডিরেক্ট যা নিরাপত্তার ফাঁক খুলে না
রিডিরেক্ট গুলো নীরবে আপনার অ্যাক্সেস কন্ট্রোলকে উল্টে দিতে পারে যদি আপনি সেগুলোকে অবিশ্বাসযোগ্য হিসেবে ধরেন।
সাধারণ প্যাটার্ন: যখন ব্যবহারকারী লগআউট থাকে, তাদের Login-এ পাঠান এবং বর্তমান পাথকে returnTo কুয়েরি প্যারামিটার হিসেবে যোগ করুন। লগইনের পরে এটি পড়ে সেখানে নিয়ে যান। ঝুঁকি হল open redirects (ব্যবহারকারীদের অনিচ্ছাকৃত জায়গায় পাঠানো) এবং লুপ।
আচরণ সহজ রাখুন:
- লগআউট ব্যবহারকারীকে Login-এ পাঠান এবং
returnTo-তে বর্তমান পাথ রাখুন। - লগইন আছে কিন্তু অনুমোদন নেই এমন ব্যবহারকারীকে dedicated
Forbiddenপেজে পাঠান (Login নয়)। - কেবল অভ্যন্তরীণ
returnToমানগুলোই অনুমোদন করুন যেগুলো আপনি চিনেন। - একটি লুপ চেক যোগ করুন যাতে আপনি কখনই একই জায়গায় রিডিরেক্ট না করেন।
const allowedReturnTo = (to) => {
if (!to || typeof to !== 'string') return null
if (!to.startsWith('/')) return null
// optional: only allow known prefixes
if (!['/app', '/admin', '/tickets'].some(p => to.startsWith(p))) return null
return to
}
router.beforeEach((to) => {
if (!auth.isReady) return false
if (!auth.isLoggedIn && to.name !== 'Login') {
return { name: 'Login', query: { returnTo: to.fullPath } }
}
if (auth.isLoggedIn && !canAccess(to, auth.user) && to.name !== 'Forbidden') {
return { name: 'Forbidden' }
}
})
নেভিগেশনের সময় সীমাবদ্ধ ডেটা লিক হওয়া এড়ান
সবচেয়ে সহজ লিক হল ইউজার অনুমোদিত কি না তা জানা আগে ডেটা লোড করা।
Vue-তে এটা প্রায়ই ঘটে যখন একটি পেজ setup()-এ ডেটা ফেচ করে এবং রাউটার গার্ড একটু পরে চলে। এমনই হলে, যদিও ব্যবহারকারী রিডিরেক্ট পায়, রেসপন্সটি একটি শেয়ার্ড স্টোরে পৌঁছে যেতে পারে বা মূহুর্তের জন্য স্ক্রিনে ফ্ল্যাশ করতে পারে।
একটি নিরাপদ নিয়ম: প্রথমে অথোরাইজ করুন, তারপর লোড করুন।
// router guard: authorize before entering the route
router.beforeEach(async (to) => {
await auth.ready() // ensure roles are known
const required = to.meta.requiredRole
if (required && !auth.hasRole(required)) {
return { name: 'forbidden' }
}
})
এছাড়াও দ্রুত নেভিগেশনের সময় পরে আসা রিকোয়েস্টগুলো সাবধানতা রাখুন। অনুরোধগুলো cancel করুন (উদাহরণ: AbortController) অথবা রেসপন্সগুলোকে ignore করুন একটি অনুরোধ আইডি চেক করে।
ক্যাশিং আরেকটা ফাঁদ। যদি আপনি গ্লোবালি “last loaded customer record” রাখেন, একটি অ্যাডমিন-শুধু রেসপন্স পরে একটি নন-অ্যাডমিনকে দেখানো হতে পারে। ক্যাশগুলোকে ইউজার আইডি ও রোল দিয়ে কী করুন, এবং লগআউট বা রোল পরিবর্তন হলে সংবেদনশীল মডিউলগুলো ক্লিয়ার করুন।
কয়েকটি অভ্যাস বেশিরভাগ লিক প্রতিরোধ করে:
- অনুমোদন নিশ্চিত হওয়া ছাড়া সংবেদনশীল ডেটা ফেচ করবেন না।
- কেচ করা ডেটা ইউজার ও রোল দিয়ে কী করুন, বা পেজ-লোকাল রাখুন।
- রুট পরিবর্তনে চলমান রিকোয়েস্টগুলো cancel বা ignore করুন।
বন্ধুত্বপূর্ণ ফলব্যাক: 401, 403, এবং not found
“না” রাস্তাগুলো “হ্যাঁ” রাস্তাগুলোর মতই গুরুত্বপূর্ণ। ভালো fallback পেজ ব্যবহারকারীকে অভিমুখে রাখে এবং সাপোর্ট অনুরোধ কমায়।
401: লগইন দরকার (অথেনটিকেটেড নয়)
ব্যবহার করুন 401 যখন ব্যবহারকারী সাইন ইন করেনি। বার্তাটি সোজাসুজি রাখুন: চলতে হলে তাদের লগইন করতে হবে। যদি আপনি পোস্ট-লগইন রিটার্ন সাপোর্ট করেন, রিটার্ন পাথ ভ্যালিডেট করুন যাতে তা আপনার অ্যাপের বাইরে যেতে না পারে।
403: এক্সেস অস্বীকৃত (অথেনটিকেটেড, কিন্তু অনুমোদন নেই)
403 তখন ব্যবহার করুন যখন ব্যবহারকারী সাইন ইন আছে কিন্তু পারমিশন নেই। নিরপেক্ষ রাখুন এবং সংবেদনশীল বিবরণ ইঙ্গিত করবেন না।
একটি শক্ত 403 পেজ সাধারণত একটি স্পষ্ট টাইটেল ("Access denied"), এক বাক্যের ব্যাখ্যা, এবং একটি নিরাপদ পরবর্তী পদক্ষেপ (ড্যাশবোর্ডে ফিরে যাওয়া, অ্যাডমিনের সাথে যোগাযোগ, যদি সাপোর্ট করে তবে অ্যাকাউন্ট পরিবর্তন) থাকে।
404: না পাওয়া গিয়েছে
404 আলাদাভাবে হ্যান্ডল করুন 401/403 থেকে। অন্যথায় মানুষ ধরে নেবে তাদের অনুমতি নেই যখন আসলে পেজটি নেই।
সাধারণ ভুলগুলো যা অ্যাক্সেস কন্ট্রোল ভেঙে দেয়
অধিকাংশ অ্যাক্সেস কন্ট্রোল বাগ সাধারণ লজিক স্লিপ থেকে আসে যা রিডিরেক্ট লুপ, ভুল পেজ ফ্ল্যাশ, বা ব্যবহারকারীদের আটকে থাকার রূপে দেখা যায়।
সাধারণ অপরাধীরা:
- লুকানো UI-কে “নিরাপত্তা” ভাবা। সবসময় রাউটারে রোল প্রয়োগ করুন এবং API-তেও।
- লগআউট/লগইন শেষে স্টেলে থাকা স্টেট থেকে রোল পড়া।
- অনুমোদনহীন ব্যবহারকারীকে অন্য একটি প্রোটেক্টেড রুটে রিডিরেক্ট করা (তারপর তাত্ক্ষণিক লুপ)।
- রিফ্রেশে “auth এখনো লোড হচ্ছে” মুহূর্ত উপেক্ষা করা।
- 401 ও 403 গুলোর মিশানো, যা ব্যবহারকারীদের বিভ্রান্ত করে।
একটি বাস্তব উদাহরণ: একটি সাপোর্ট এজেন্ট লগআউট করে এবং একই শেয়ার্ড কম্পিউটারে একটি অ্যাডমিন লগইন করে। যদি আপনার গার্ড নতুন সেশনের নিশ্চিত না হওয়া পর্যন্ত ক_cached রোল পড়ে নেয়, তাহলে আপনি ভুলভাবে অ্যাডমিনকে ব্লক করতে পারেন বা, আরো খারাপ, সাময়িকভাবে অনধিকৃত অ্যাক্সেস দিতে পারেন।
শিপ করার আগে দ্রুত চেকলিস্ট
একটি ছোট পাস করুন যা সেই মুহূর্তগুলোতে ফোকাস করে যেখানে সাধারণত অ্যাক্সেস কন্ট্রোল ভেঙে যায়: ধীর নেটওয়ার্ক, মেয়াদোত্তীর্ণ সেশন, এবং বুকমার্কেড URL।
- প্রতিটি প্রোটেক্টেড রুটের স্পষ্ট
metarequirements আছে। - গার্ডগুলো auth-লোডিং স্টেট হ্যান্ডেল করে যাতে প্রোটেক্টেড UI ফ্ল্যাশ না হয়।
- অনুমোদনহীন ব্যবহারকারী একটি স্পষ্ট 403 পেতে পারে (হোমে কনফিউজিং বাউন্স নয়)।
- যে কোনো “return to” রিডিরেক্ট ভ্যালিডেটেড এবং লুপ তৈরি করে না।
- সংবেদনশীল API কলগুলো শুধুমাত্র অনুমোদন নিশ্চিত হওয়ার পরে চলে।
তারপর একটি দৃশ্যপট পরীক্ষা করুন end-to-end: সাইন আউট অবস্থায় একটি প্রোটেক্টেড URL নতুন ট্যাবে খুলুন, একটি বেসিক ইউজার হিসেবে লগইন করুন, এবং নিশ্চিত করুন আপনি বা তো অনুমোদিত পেজে land করেন (যদি অনুমোদিত) বা একটি পরিষ্কার 403 দেখেন পরবর্তী ধাপসহ।
উদাহরণ: একটি ছোট ওয়েব অ্যাপে support বনাম admin অ্যাক্সেস
ধরা যাক একটি হেল্পডেস্ক অ্যাপ যেখানে দুইটি রোল আছে: support এবং admin। Support টিকিট পড়তে এবং উত্তর দিতে পারে। Admin-ও তা করতে পারে, প্লাস বিলিং ও কোম্পানি সেটিংস পরিচালনা করতে পারে।
/tickets/:idআছেsupportএবংadmin-এর জন্য/settings/billingশুধুমাত্রadmin-এর জন্য
এখন একটি সাধারণ মুহূর্ত: একটি support এজেন্ট একটি পুরোনো বুকমার্ক থেকে ডিপ লিংক /settings/billing খুলে। গার্ড রুট meta চেক করে পেজ লোড হওয়ার আগে নেভিগেশন ব্লক করা উচিত। কারণ ব্যবহারকারী লগইন করেছে কিন্তু রোল নেই, তাদের একটি নিরাপদ ফলব্যাক (403) দেখানো উচিত।
দুইটি বার্তা গুরুত্বপূর্ণ:
- Login required (401): “Please sign in to continue.”
- Access denied (403): “You do not have access to Billing Settings.”
কি হওয়া উচিত না: বিলিং কম্পোনেন্ট মাউন্ট হওয়া, বা বিলিং ডেটা ফেচ হওয়া এমনকি ক্ষণিকের জন্যও।
মধ্য-সেশনে রোল পরিবর্তন আরেকটা এজ কেস। যদি কেউ প্রোমোট বা ডিগ্রেড হয়, মেনুর ওপরে ভরসা করবেন না। নেভিগেশনে রোলগুলো পুনরায় চেক করুন এবং সিদ্ধান্ত নিন সক্রিয় পেজগুলো কিভাবে হ্যান্ডল করবেন: প্রোফাইল পরিবর্তনে auth স্টেট রিফ্রেশ করুন, বা রোল পরিবর্তন সনাক্ত করে এমন পেজগুলো থেকে রিডিরেক্ট করুন যেগুলো আর অনুমোদিত নেই।
পরবর্তী পদক্ষেপ: অ্যাক্সেস রুলগুলো টেকসই রাখুন
একবার গার্ডগুলো কাজ করলে, বড় ঝুঁকি হল drift: একটি নতুন রুট meta ছাড়া শিপ হয়, একটি রোল রিনেম হয়, এবং রুলগুলো অসামঞ্জস্যপূর্ণ হয়ে ওঠে।
নিয়মিত করে একটি ছোট টেস্ট প্ল্যান রাখুন যা আপনি প্রতিটি রুট যোগ করলে চালাতে পারেন:
- Guest হিসেবে: প্রোটেক্টেড রুট খুলুন এবং নিশ্চিত করুন আপনি লগইন পেজে land করেন এবং আংশিক কন্টেন্ট দেখা যায় না।
- User হিসেবে: একটি পেজ খুলুন যা আপনাকে অ্যাক্সেস থাকা উচিত নয় এবং নিশ্চিত করুন আপনি একটি পরিষ্কার 403 পান।
- Admin হিসেবে: অ্যাড্রেস বার থেকে কপি করা ডিপ লিংকগুলো চেষ্টা করুন।
- প্রতিটি রোলের জন্য: প্রোটেক্টেড রুটে রিফ্রেশ করে ফলাফল স্থিতিশীল কিনা দেখুন।
যদি আপনি আরো একটি সেফটি নেট চান, একটি dev-only ভিউ বা কনসোল আউটপুট রাখুন যা রুটগুলো এবং তাদের meta requirements তালিকাভুক্ত করে, যাতে মিসিং রুলগুলো তৎক্ষণাৎ চোখে পড়ে।
যদি আপনি অভ্যন্তরীণ টুল বা পোর্টাল AppMaster (appmaster.io) দিয়ে বানান, একই পদ্ধতি প্রয়োগ করুন: Vue3 UI-এ রাউট গার্ডগুলোকে নেভিগেশনে ফোকাস রাখতে দিন, এবং পারমিশনগুলো যেখানে ডেটা ও লজিক থাকে সেখানে—ব্যাকএন্ডে—প্রয়োগ করুন।
একটি উন্নতি বেছে নিন এবং সেটি end-to-end বাস্তবায়ন করুন: ডেটা-ফেচ গেটিং শক্তিশালী করুন, 403 পেজ উন্নত করুন, বা রিডিরেক্ট হ্যান্ডলিং লক ডাউন করুন। ছোট ছোট ফিক্সগুলোই বেশিরভাগ বাস্তব-জগতের অ্যাক্সেস বাগ থামায়।
প্রশ্নোত্তর
Route guards কেবল নেভিগেশন নিয়ন্ত্রণ করে, ডেটা অ্যাক্সেস নয়। এগুলো পেজ ব্লক করা, রিডিরেক্ট দেওয়া এবং পরিষ্কার 401/403 স্টেট দেখাতে সাহায্য করে, কিন্তু কেউ সরাসরি আপনার API কল করলে তা থামাতে পারবে না। সর্বদা ব্যাকএন্ডেও একই অনুমোদন প্রয়োগ করুন যাতে সীমিত ডেটা কখনও ফিরিয়ে না দেওয়া হয়।
UI লুকানো কেবল কাউকে কী দেখা যায় সেটা বদলে দেয়, কি অনুরোধ করা যায় সেটা নয়। ব্যবহারকারীরা URL টাইপ করে, বুকমার্ক খুলে বা ডিপ লিংক অ্যাক্সেস করে থাকতে পারে। রাউটার চেক দিতে হবে পেজ ব্লক করার জন্য, এবং সার্ভার-সাইড অথোরাইজেশন দিতে হবে ডেটা ব্লক করার জন্য।
প্রথমে সহজ একটি সেট দিয়ে শুরু করুন যা সবাই বোঝে, পরে প্রয়োজন হলে পারমিশন যোগ করুন। সাধারণ বেসলাইন: admin, support, এবং viewer। নির্দিষ্ট ক্রিয়াগুলোর জন্য tickets:read বা audit:read মতো পারমিশন যোগ করুন। “কে আপনি” (role) আলাদা রাখুন এবং “আপনি কী করতে পারবেন” (permission) আলাদা—এভাবে বোঝা সহজ থাকে।
রুট রেকর্ডের meta-তে একসাথে নিয়ম রাখুন—যেমন requiresAuth, roles, এবং permissions। এতে রুলগুলো সেই পেজের পাশে থাকে এবং গ্লোবাল গার্ড predictable হয়। নেস্টেড রুটের জন্য to.matched-এর সব রেকর্ড চেক করুন যাতে প্যারেন্টের শর্তগুলো স্কিপ না হয়।
to.matched থেকে পড়ুন এবং সব ম্যাচ করা রেকর্ডের requirements মিশ্রিত করুন। এভাবে child রুট প্যারেন্টের requiresAuth বা roles বাইপাস করতে পারবে না। আগে থেকে একটি স্পষ্ট merge নিয়ম ঠিক করুন (সাধারণত: প্যারেন্টের শর্তগুলো children-এ প্রযোজ্য)।
গার্ড চালু হতে পারে অ্যাপ যখন এখনও ইউজারের পরিচয় জানে না—এটিই ফ্ল্যাশ বা লুপের কারণ। auth কে তিনটি স্টেটে দেখুন—unknown, logged out, logged in—এবং auth unknown থাকা অবস্থায় কখনই রোল পড়বেন না। একটি ইনিশিয়ালাইজেশন (যেমন একবারের “who am I” রিকোয়েস্ট) শেষ না হওয়া পর্যন্ত গার্ড অপেক্ষা করান।
গ্লোবাল beforeEach দিয়ে সাধারণ নিয়মগুলো (চাহিদা: লগইন, রোল/পারমিশন) প্রয়োগ করুন। beforeEnter ব্যবহার করুন কেবল তখনই যখন রুল সত্যিই রুট-নির্দিষ্ট এবং params-এর উপর নির্ভর করে—উদাহরণ: “শুধু টিকিটের মালিকই এই পেজ দেখতে পারবে”। উভয় ক্ষেত্রেই একই auth সিংগল সোর্স ব্যবহার করুন।
returnTo কখনোই বিশ্বাসযোগ্য ইনপুট হিসেবে গ্রহণ করবেন না। কেবলই অভ্যন্তরীণ পাথগুলো অনুমোদন করুন (উদাহরণ: / দিয়ে শুরু এবং পরিচিত প্রিফিক্সে মিল)। একটি লুপ চেক রাখুন যাতে একই ব্লক হওয়া রুটে পুনরায় রিডিরেক্ট না ঘটে। লগআউট অবস্থায় লোকজন Login-এ যান; লগইন করা কিন্তু অনুমোদনহীন ব্যবহারকারীকে 403 পেজ দেখান।
প্রথমে অনুমোদনটি নিশ্চিত করে তারপরই ডেটা আনুন। যদি পেজ setup()-এ ডেটা ফেচ করে এবং পরে রিডিরেক্ট ঘটে, রেসপন্সটি স্টোরে landen করে বা সাময়িকভাবে দেখাতে পারে। সংবেদনশীল রিকোয়েস্টগুলো অনুমোদন নিশ্চিত হওয়ার পরে চালান, এবং নেভিগেশন পরিবর্তলে চলতি অনুরোধগুলো cancel বা ignore করুন।
401: ব্যবহারকারী সাইন ইন করেনি—তাদের সাইন ইন করতে বলুন। 403: ব্যবহারকারী সাইন ইন আছে কিন্তু অনুমতি নেই—এটি নিরপেক্ষ এবং সংবেদনশীল তথ্যের ইঙ্গিত না করে। 404: আলাদা রাখুন যাতে কেউ ভাবতে না পারে যে পেজটি নেই বলে তারা অনুমোদিত নয়। স্পষ্ট এবং ধারাবাহিক fallback গুলো ব্যবহারকারীকে বিভ্রান্তি কমায়।


