السلام عليكم،
في تطبيقات React.js، موضوع الحماية دائمًا من الأمور الحساسة والمهمة، وفي الغالب يكون الأسلوب المستخدم كالتالي:
بعد تسجيل الدخول أو إنشاء مستخدم جديد، نقوم بالحصول على Token ثم نخزنه في الذاكرة المحلية مثل localStorage أو cookies.
لكن للأسف، هذه الطريقة ضعيفة من ناحية الحماية، لأنها معرضة لهجمات مثل XSS (Cross-Site Scripting).
الطريقة الثانية هي حفظ بيانات المستخدم في الذاكرة المؤقتة (in-memory) داخل كائنات React، مما يوفر حماية أكبر لأن البيانات لا تُخزن في المتصفح بشكل دائم، ولكن المشكلة هنا أن هذه البيانات تُفقد بمجرد تحديث الصفحة أو إعادة تحميلها.
الحل الوسط الذي وجدته هو التالي:
في النظم الخلفية (Backend)، ننشئ Token محمي باستخدام httpOnly cookie، بحيث لا يمكن الوصول إليه من جافاسكريبت في المتصفح، مما يقلل خطر هجمات XSS.
مثال على إنشاء Token وتخزينه كـ httpOnly cookie:
const generateToken = (res, userId) => {
const token = jwt.sign({ userId }, process.env.JWT_SECRET, {
expiresIn: '30d',
});
// تعيين الـ JWT كـ httpOnly cookie
res.cookie('jwt', token, {
httpOnly: true,
secure: process.env.NODE_ENV !== 'development', // لتأمين الكوكيز في بيئة الإنتاج
sameSite: 'strict', // لمنع هجمات CSRF
maxAge: 30 * 24 * 60 * 60 * 1000, // مدة 30 يومًا
});
return token;
};
ثم ننشئ نقطة نهاية (endpoint) لاسترجاع بيانات المستخدم مع بعض المعلومات الضرورية، مثل:
const getMe = asyncHandler(async (req, res) => {
const user = await User.findById(req.user._id).select('-password');
// استرجاع التوكن من الكوكيز
const token = req.cookies.jwt;
res.json({
_id: user._id,
name: user.name,
email: user.email,
isAdmin: user.isAdmin,
token, // نُرسل التوكن أيضاً للواجهة الأمامية
});
});
في الواجهة الأمامية، سأستخدم مكتبة tanstack query، التي توفر طريقة مرنة وفعالة للتعامل مع الـ API، مع دعم مدمج للـ caching.
سأقوم بجلب بيانات المستخدم من نقطة النهاية getMe وأحتفظ بها في الذاكرة (in-memory) داخل React. بهذه الطريقة نحقق التوازن بين:
حماية البيانات لأن التوكن مخزن كـ httpOnly cookie غير قابل للوصول من جافاسكريبت مباشرةً.
سهولة الوصول المستمر للبيانات في الواجهة الأمامية بدون فقدانها عند تحديث الصفحة.
يسعدني جداً سماع آرائكم وملاحظاتكم، فهذه الطريقة نابعة من فكرة محلية، وبالتالي فكل ملاحظة منكم قيمة وستفيدني كثيرًا في تحسين الأمان والأداء.
شكرًا لكم!