يتطلب مستوى: متوسط — الدليل مناسب لمن يعرف أساسيات Node.js و Express ويريد تأمين تسجيل الدخول بطريقة احترافية. لو أنت مبتدئ تمامًا، فيه في الطريق مثال مبسّط يقرّب الفكرة قبل الكود.
مصادقة JWT بـ Access و Refresh Token في Node.js
في نهاية الدليل هيبقى عندك نظام دخول يخلّي المستخدم مسجّلًا أسبوعًا كاملًا، من غير ما تسيب توكن خطير على جهازه طول المدة. الفكرة: توكن وصول عمره 15 دقيقة، وتوكن تجديد عمره 7 أيام يتدوّر مع كل استخدام.
المشكلة باختصار
لو حطّيت توكن واحد عمره أسبوع، أي تسريب له يفتح حساب المستخدم أسبوعًا كاملًا. ولو خلّيته قصيرًا جدًا، المستخدم هيتطرد كل ربع ساعة. الحل مش توكن أطول ولا أقصر، الحل توكنين بمهمتين مختلفتين.
مثال يقرّب الفكرة ثم الشرح الدقيق
تخيّل فندقًا. ساعة الوصول بيدّيك بطاقة غرفة تفتح الباب، بس بتنتهي كل يوم. بدل ما ترجع الاستقبال كل يوم بجواز سفرك، عندك إيصال حجز في الخزنة يخلّي الاستقبال يجدّد البطاقة بسرعة. البطاقة اليومية هي توكن الوصول، وإيصال الحجز هو توكن التجديد.
علميًا: الـ JWT توكن موقّع رقميًا يحمل بيانات (مثل معرّف المستخدم ودوره) وتوقيعًا. السيرفر بيتحقق من التوقيع بمفتاحه السرّي بدون رجوع لقاعدة البيانات. توكن الوصول (Access) قصير ويُرسل مع كل طلب في ترويسة Authorization. توكن التجديد (Refresh) طويل ووظيفته الوحيدة: إصدار توكن وصول جديد لما القديم ينتهي.
الافتراض هنا: عندك API واحد يشتغل على HTTPS، ومخزن للتوكنات (PostgreSQL أو Redis). الأرقام في المقال مبنية على سيناريو ~50 ألف مستخدم نشِط يوميًا.
الخطوات
- جهّز المشروع. ركّب الحزم الأساسية.
mkdir jwt-auth && cd jwt-auth
npm init -y
npm install express jsonwebtoken bcryptjs cookie-parser- ولّد مفتاحين سرّيين منفصلين. مفتاح للوصول ومفتاح للتجديد، عشان لو اتسرّب واحد ما ينهارش التاني.
echo "ACCESS_SECRET=$(openssl rand -hex 32)" >> .env
echo "REFRESH_SECRET=$(openssl rand -hex 32)" >> .env- اكتب دوال توقيع التوكنات. الوصول 15 دقيقة، التجديد 7 أيام، وكل توكن تجديد له معرّف فريد (jti) هنستخدمه في التدوير.