আগের পর্বে access token-এর মেয়াদ ছোট রেখেছিলাম নিরাপত্তার জন্য। কিন্তু তাহলে user-কে তো ১৫ মিনিট পরপর login করতে হবে - সেটা তো চলবে না। সমাধান হলো দুটো token-এর জুটি: ছোট মেয়াদের access token প্রতিদিনের কাজের জন্য, আর লম্বা মেয়াদের refresh token শুধু নতুন access token পাওয়ার জন্য।
Refresh token rotation কীভাবে কাজ করে
Flow-টা এরকম: access token expire হলে frontend refresh token দিয়ে নতুন access token চায়। Server শুধু নতুন access-ই দেয় না, নতুন refresh token-ও দেয় - আর পুরনো refresh token-টা বাতিল করে দেয়। এটাই rotation। সুবিধা হলো, refresh token চুরি হলেও চোর সেটা একবার ব্যবহার করলেই ধরা পড়ার ব্যবস্থা করা যায় - কারণ আসল user পরে পুরনো token দিয়ে এলে server বুঝবে কিছু একটা গণ্ডগোল আছে, তখন সব token বাতিল করে দেওয়া যায়। Refresh token-এর একটা hash database-এ রাখা হয়, যাতে বাতিল করাটা সম্ভব হয়।
// নতুন access token দেওয়ার endpoint
app.post("/auth/refresh", async (req, res) => {
const token = req.cookies.refreshToken;
const saved = await db.refreshToken.findFirst({ where: { tokenHash: hash(token) } });
if (!saved) return res.status(401).json({ success: false, message: "Session expired" });
await db.refreshToken.delete({ where: { id: saved.id } }); // পুরনোটা বাতিল
// এখানে নতুন access + নতুন refresh token বানিয়ে পাঠান
});httpOnly cookie কেন
Refresh token-টা রাখা হয় httpOnly cookie-তে। HttpOnly মানে JavaScript দিয়ে এই cookie পড়া যায় না - তাই site-এ কোনো XSS bug থাকলেও attacker refresh token চুরি করতে পারবে না। Access token-এর তুলনায় refresh token অনেক বেশি ক্ষমতাশালী (এটা দিয়ে বারবার নতুন access পাওয়া যায়), তাই এর সুরক্ষাও বেশি কড়া। সাথে secure আর sameSite flag ব্যবহার করুন।
Role-based access - সবাই সব পারবে না
Login থাকা মানেই সব করার অনুমতি নয়। Admin panel-এর route-এ সাধারণ user ঢুকতে পারবে না। এটা middleware দিয়েই হয় - আগের পর্বের requireAuth-এর পর আরেকটা ধাপ:
function requireRole(...roles) {
return (req, res, next) => {
if (!roles.includes(req.user.role)) {
return res.status(403).json({ success: false, message: "Forbidden" });
}
next();
};
}
router.delete("/users/:id", requireAuth, requireRole("admin"), deleteUser);401 আর 403-এর পার্থক্য খেয়াল করুন - 401 মানে 'আপনি কে জানি না' (login নেই), 403 মানে 'আপনি কে জানি, কিন্তু এই কাজের অনুমতি নেই'। Logout-এর সময় database থেকে refresh token মুছে দিন আর cookie clear করুন - তাহলেই session সত্যিকারের শেষ হবে।
সবাই যে ভুলটা করে
দুটো ভুল খুব দেখা যায়: refresh token localStorage-এ রাখা (XSS হলেই চুরি হয়ে যাবে), আর role check শুধু frontend-এ করা (button লুকিয়ে রাখলেই নিরাপদ না - API-তে সরাসরি request পাঠালেই কাজ হয়ে যাবে)। অনুমতির আসল check সবসময় server-এ।
আজকের Practice
আপনার auth-এ refresh token যোগ করুন - login-এ httpOnly cookie-তে refresh token পাঠান, /auth/refresh endpoint বানান rotation সহ, আর logout-এ token বাতিল করুন। তারপর একটা admin-only route বানিয়ে সাধারণ user দিয়ে ঢোকার চেষ্টা করে দেখুন 403 আসে কিনা।
Interview-এ কীভাবে বলবেন
আমি ছোট মেয়াদের access token আর rotation সহ refresh token ব্যবহার করি। Refresh token থাকে httpOnly cookie-তে, যাতে XSS-এ চুরি না হয়, আর তার hash database-এ রাখি যাতে logout বা সন্দেহজনক ব্যবহারে বাতিল করা যায়। Role-based access middleware দিয়ে enforce করি - frontend-এর উপর ভরসা করি না।