شرح JWT و Refresh Token مع API بطريقة بسيطة

x32x01
  • بواسطة x32x01 ||

😅 بلاش تتعامل مع API نص النهار… خصوصًا مع JWT​

خلّينا متفقين من الأول: التعامل مع API + Authentication ممكن يقلب صداع لو اتعمل غلط 🤯
اللي قدامنا هنا API بسيط وظيفته:
  • يعمل اتصال بالسيرفر
  • يبعث Requests
  • يستقبل Responses
وطبعًا مستخدمين JWT Authentication علشان نأمّن اليوزر.

🔐 JWT Authentication بيشتغل إزاي؟​

أول ما اليوزر يدخل credentials صح:
  • السيرفر يرجّع:
    • Access Token
    • Refresh Token
كل واحد ليه دور محدد 👇


⏳ Access Token وظيفته إيه؟​

  • بيخلّي اليوزر داخل الموقع
  • ليه مدة صلاحية قصيرة
  • أول ما يخلص: اليوزر يبقى Unauthorized (401)
وده الطبيعي… ومهم للأمان 🛡️


♻️ Refresh Token بيعمل إيه؟​

  • بيتستخدم لما الـ Access Token ينتهي
  • نبعته للسيرفر
  • يرجّع Access Token جديد
  • من غير ما اليوزر يحس أو يتسجل خروج
📌 ده اللي بنسميه Silent Refresh


🤔 طب نعمل Refresh إزاي من غير ما اليوزر يحس؟​

هنا بقى نخش في الجزء النضيف 😎 لما أي Request يرجع 401 Unauthorized:
  • نعرف إن الـ Access Token انتهى
  • نعمل Retry للطلب
  • بس بشرط: ما نعملش Loop لا نهائي


🧠 الفكرة الأساسية (Logic)​

  1. الطلب يرجع 401
  2. نتأكد إننا مجربناش نعمل Retry قبل كده
  3. نبعث Refresh Token
  4. نستلم Access Token جديد
  5. نعيد الطلب الأصلي
  6. اليوزر مكمّل عادي 👌


⚙️ تطبيق الكلام ده باستخدام Axios Interceptors​

🟢 Interceptor قبل الـ Request​

JavaScript:
axios.interceptors.request.use(config => {
  const token = localStorage.getItem('access');

  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }

  return config;
});


🔴 Interceptor بعد الـ Response (الأهم)​

JavaScript:
axios.interceptors.response.use(
  res => res,
  async error => {
    const originalRequest = error.config;

    if (
      error.response?.status === 401 &&
      !originalRequest._retry
    ) {
      originalRequest._retry = true;

      const refreshToken = localStorage.getItem('refresh');

      if (!refreshToken) {
        logout();
        return Promise.reject(error);
      }

      try {
        const res = await axios.post('/auth/refresh', {
          refresh: refreshToken
        });

        localStorage.setItem('access', res.data.access);

        originalRequest.headers.Authorization =
          `Bearer ${res.data.access}`;

        return axios(originalRequest);
      } catch (err) {
        logout();
        return Promise.reject(err);
      }
    }

    return Promise.reject(error);
  }
);
📌 ليه async / await؟ علشان JavaScript Asynchronous ولو مستنتش الـ response، هتاخد undefined أو null.


🚪 إمتى نعمل Logout؟​

  • مفيش Refresh Token
  • أو الـ Refresh Token نفسه منتهي
  • أو السيرفر رفض الطلب

🧹 تنظيف التوكنات​

JavaScript:
localStorage.removeItem('access');
localStorage.removeItem('refresh');
وبعدها:
  • تحويل اليوزر على صفحة Login


🧩 يعني إيه Interceptors؟​

Interceptors ببساطة:
  • حاجة بتحصل:
    • قبل الـ Request
    • وبعد الـ Response
تتحكم في:
  • Headers
  • Errors
  • Retry logic
  • Authentication flow


📦 التوكنات بتتخزن فين؟​

عندك كذا اختيار:
  • localStorage
  • Cookies
  • httpOnly Cookies
  • State Management


⚠️ هل localStorage آمن؟​

الإجابة المختصرة: لا 100%

المشكلة الأساسية:​

  • عرضة لـ XSS Attacks
  • لو حصل Injection، التوكن سهل يتسرق

الأفضل:​

  • httpOnly Cookies
  • أو Hybrid Solution حسب المشروع
📌 مفيش حل كامل… كله Trade-offs


✅ الخلاصة​

  • JWT System صح = تجربة مستخدم ممتازة
  • Access Token قصير = أمان
  • Refresh Token ذكي = راحة
  • Interceptors = تحكم كامل
📌 الأمان مش في الكود بس الأمان في التفكير قبل التنفيذ
 
المواضيع ذات الصلة
x32x01
الردود
0
المشاهدات
175
x32x01
x32x01
x32x01
الردود
0
المشاهدات
558
x32x01
x32x01
x32x01
الردود
0
المشاهدات
534
x32x01
x32x01
x32x01
الردود
0
المشاهدات
873
x32x01
x32x01
x32x01
الردود
0
المشاهدات
897
x32x01
x32x01
الدخول أو التسجيل السريع
نسيت كلمة مرورك؟
إحصائيات المنتدى
المواضيع
2,275
المشاركات
2,487
أعضاء أكتب كود
547
أخر عضو
exozonlyperson
عودة
أعلى