لقد أفسدتُ إعداد Next.js Auth Matcher الخاص بي ثلاث مرات
لقد تسببتُ في تعطل ثلاثة مشاريع قبل أن أفهم كيفية عمل proxy.ts في Next.js 16.
كان الخطأ صامتاً. لا سجلات (logs). لا تحذيرات. لا أخطاء. فقط عمليات إعادة توجيه (redirects) معطلة وثغرات أمنية.
إذا كنت تقوم بالترقية إلى Next.js 16، فلا تكتفِ بمجرد تشغيل codemod ثم ترحل. عليك التحقق من هذه الأشياء الثلاثة.
فخ عملية الترقية
قامت Next.js بتغيير اسم middleware.ts إلى proxy.ts. هذا ليس مجرد تغيير في الاسم.
- كان
middleware.tsيعمل على الـ Edge runtime، وكان لديه دعم محدود لـ crypto. - يعمل
proxy.tsعلى الـ Node.js runtime بشكل افتراضي، ويتمتع بدعم كامل لـ crypto.
إذا قمت بتحديث حزمتك يدوياً بدون استخدام codemod، فقد يظل ملف middleware.ts القديم موجوداً. سيتم تجميعه (compile) بشكل صحيح، وسيجتاز فحوصات TypeScript، لكنه لن يفعل شيئاً. لن يتم اعتراض المسارات (routes) الخاصة بك، ولن تعمل عمليات إعادة التوجيه (redirects).
تحقق من هذه الأشياء الثلاثة يدوياً:
- يجب أن يتواجد
proxy.tsفي جذر المشروع (project root). - يجب أن يكون اسم الدالة المصدرة (exported function) هو
proxy. - يجب حذف
middleware.ts.
فجوة الـ Matcher
الـ matcher هو المكان الذي تفشل فيه إعدادات المصادقة (auth) في أغلب الأحيان.
إذا كان الـ matcher واسعاً جداً، فسيتم تشغيل الـ proxy على كل ملف CSS وصورة، مما يتسبب في حلقات إعادة توجيه (redirect loops) لا نهائية.
وإذا كان الـ matcher ضيقاً جداً، فستخلق ثغرة أمنية.
إذا لم يكن المسار (route) موجوداً في الـ matcher الخاص بك، فلن يعمل الـ proxy أبداً. يمكن للمستخدم إرسال ترويسات (headers) خاصة به إلى ذلك المسار. وإذا كان الـ Server Component الخاص بك يثق في تلك الترويسات، فيمكن للمهاجم انتحال شخصية أي شخص.
الحل: لا تثق بالترويسات
لقد تعلمت ذلك بالطريقة الصعبة: لا تعتمد فقط على الترويسات (headers) التي يمررها الـ proxy.
استخدم نهج الطبقتين:
- يعمل الـ proxy كبوابة سريعة عند حدود الشبكة.
- يقوم الـ Server Component بالتحقق من الـ JWT مباشرة من ملف تعريف الارتباط (cookie) في وقت العرض (render time).
هذا الفحص الثاني يغلق الفجوة. حتى لو أغفل الـ matcher مساراً ما، فإن الـ Server Component سيكشف المستخدم غير المصرح له. هذا يضيف بضع أجزاء من الثانية من التأخير (latency) ولكنه يمنع فشلاً أمنياً جسيماً.
قائمة التحقق الملخصة:
- استخدم
proxy.tsللمصادقة (auth). - استخدم Node.js runtime للحصول على دعم كامل لـ crypto.
- قم بتعيين الترويسات (headers) في الطلب (request)، وليس في الاستجابة (response).
- تحقق دائماً من الـ JWT داخل الـ Server Components.