Backend Security Layer

JSON Web Token (JWT) Security: Best Practices for Token Architecture

ব্যাকএন্ডে ইউজার সেশন ট্র্যাকিং বা অথেনটিকেশনের জন্য **JSON Web Token (JWT)** একটি স্ট্যান্ডার্ড সলিউশন। তবে অনেক ডেভলপার টোকেন জেনারেট করার পর তা ফ্রন্টএন্ডের `localStorage` এ স্টোর করে রাখেন, যা মারাত্মক সিকিউরিটি থ্রেট। এর ফলে সাইটে কোনো কাস্টম স্ক্রিপ্ট বা XSS (Cross-Site Scripting) অ্যাটাক হলে হ্যাকার সহজেই টোকেন চুরি করে ইউজারের অ্যাকাউন্ট হাইজ্যাক করতে পারে।

সিকিউরড আর্কিটেকচারের জন্য অবশ্যই টোকেনকে **HttpOnly Cookie** এর ভেতর সেট করতে হবে, যা জাভাস্ক্রিপ্ট দিয়ে রিড করা অসম্ভব।

১. টোকেন সাইনিং এবং সিকিউর কুকি ইনজেকশন

লগইন ভেরিফিকেশনের পর কীভাবে এক্সপ্রেস অ্যাপ থেকে কাস্টম রিফ্রেশ ও অ্যাক্সেস টোকেন জেনারেট করে কুকিতে পুশ করবেন, তা নিচে দেখানো হলো:

const jwt = require('jsonwebtoken');

app.post('/api/auth/login', (req, res) => {
    // ইউজার ভেরিফিকেশন লজিক শেষ হওয়ার পর...
    const userPayload = { userId: "ahyan_dev_007", role: "admin" };

    // ১. স্বল্পমেয়াদী অ্যাক্সেস টোকেন জেনারেট (১৫ মিনিট মেয়াদ)
    const accessToken = jwt.sign(userPayload, 'ACCESS_SECRET_KEY', { expiresIn: '15m' });

    // ২. দীর্ঘমেয়াদী রিফ্রেশ টোকেন জেনারেট (৭ দিন মেয়াদ)
    const refreshToken = jwt.sign(userPayload, 'REFRESH_SECRET_KEY', { expiresIn: '7d' });

    // ৩. টোকেন দুটি অত্যন্ত সুরক্ষিত HttpOnly কুকিতে সেট করা
    res.cookie('accessToken', accessToken, {
        httpOnly: true, // জাভাস্ক্রিপ্ট চুরি প্রতিরোধ করবে
        secure: true,   // শুধুমাত্র HTTPS প্রোটোকলে কাজ করবে
        sameSite: 'strict', // CSRF অ্যাটাক প্রোটেকশন
        maxAge: 15 * 60 * 1000 // ১৫ মিনিট
    });

    res.json({ success: true, status: "Pipeline secure. Authenticated!" });
});

ধাপ ২: মিডলওয়্যার ভেরিফিকেশন গেটওয়ে

যেকোনো প্রোটেক্টেড এপিআই রাউটে রিকোয়েস্ট আসার পর ইনকামিং কুকি টোকেন ডিক্রিপ্ট এবং অথরাইজ করার সিকিউর লজিক:

const verifySecureToken = (req, res, next) => {
    // কুকি হেডার থেকে টোকেন এক্সট্র্যাক্ট করা
    const token = req.cookies.accessToken;

    if (!token) return res.status(401).json({ error: "Access denied. Token missing." });

    try {
        const verified = jwt.verify(token, 'ACCESS_SECRET_KEY');
        req.user = verified;
        next(); // পরবর্তী এক্সিকিউশনে পাস করা
    } catch (err) {
        res.status(403).json({ error: "Invalid token or session expired." });
    }
};

প্রো-টিপ: প্রোডাকশনে কখনো jwt.decode() ব্যবহার করবেন না। ডিকোড শুধুমাত্র টোকেনের ভেতরের ডেটা রিড করে কিন্তু ক্রিপ্টোগ্রাফিক সিগনেচার ভেরিফাই করে না। সবসময় jwt.verify() ব্যবহার নিশ্চিত করুন।