التفويض والمصادقة في JavaScript (Node.js)
في تطوير الويب الحديث، أمان بيانات المستخدمين هو مهمة ذات أولوية. في هذا الدليل، سنشرح المفاهيم الأساسية لـ المصادقة (التحقق من الهوية) والتفويض (تحديد الصلاحيات) في بيئة Node.js. ستتعلم كيفية تنفيذ التسجيل، تسجيل الدخول بكلمة مرور، استخدام رموز JWT وحماية المسارات.
1. المفاهيم الأساسية
- المصادقة — عملية تأكيد الهوية (مثل البريد الإلكتروني + كلمة المرور).
- التفويض — التحقق مما إذا كان للمستخدم الحق في تنفيذ إجراء (دور مشرف/مستخدم).
- JWT (JSON Web Token) — طريقة مضغوطة لنقل البيانات على شكل رمز مميز، تُستخدم غالبًا للجلسات.
- تجزئة كلمات المرور — شرط أمان إلزامي (bcrypt، argon2).
2. تثبيت التبعيات
للعمل، سنحتاج إلى حزم npm التالية:
npm install express bcryptjs jsonwebtoken dotenvexpress— إطار عمل ويبbcryptjs— تجزئة كلمات المرورjsonwebtoken— إنشاء والتحقق من JWTdotenv— إدارة المفاتيح السرية
3. تسجيل بسيط وتجزئة كلمة المرور
لننشئ نموذج مستخدم أساسي (كمثال سنستخدم مصفوفة في الذاكرة، في مشروع حقيقي استبدلها بقاعدة بيانات):
const bcrypt = require('bcryptjs');const users = []; // محاكاة قاعدة البيانات
async function registerUser(email, password) { const salt = await bcrypt.genSalt(10); const hashedPassword = await bcrypt.hash(password, salt); users.push({ email, password: hashedPassword }); console.log('تم تسجيل المستخدم:', email);}
// مثال على الاستدعاء:registerUser('user@example.com', 'myPassword123');4. المصادقة باستخدام JWT
بعد تسجيل الدخول بنجاح، نصدر للعميل رمز JWT. يحتوي الرمز على معرف المستخدم وتاريخ انتهاء الصلاحية.
const jwt = require('jsonwebtoken');require('dotenv').config();
const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key';
function loginUser(email, password) { const user = users.find(u => u.email === email); if (!user) return null;
const isValid = bcrypt.compareSync(password, user.password); if (!isValid) return null;
// إنشاء الرمز const token = jwt.sign( { userId: user.email, role: 'user' }, JWT_SECRET, { expiresIn: '1h' } ); return token;}5. الوسائط البرمجية الوسيطة لحماية المسارات
لننشئ وسيطة برمجية وسيطة (middleware) تتحقق من JWT في رأس Authorization:
function authMiddleware(req, res, next) { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
if (!token) { return res.status(401).json({ message: 'الرمز غير مقدم' }); }
try { const decoded = jwt.verify(token, JWT_SECRET); req.user = decoded; // تمرير بيانات المستخدم إلى الطلب next(); } catch (err) { return res.status(403).json({ message: 'رمز غير صالح' }); }}6. مثال على الاستخدام في Express
نجمع كل شيء معًا — ننشئ مسارات لتسجيل الدخول والملف الشخصي المحمي:
const express = require('express');const app = express();app.use(express.json());
// مسار تسجيل الدخولapp.post('/api/login', (req, res) => { const { email, password } = req.body; const token = loginUser(email, password); if (!token) { return res.status(401).json({ message: 'بيانات اعتماد غير صحيحة' }); } res.json({ token });});
// المسار المحميapp.get('/api/profile', authMiddleware, (req, res) => { res.json({ message: 'تم الوصول' });