من سه بار در Matcher احراز هویت Next.js خود اشتباه کردم
قبل از اینکه بفهمم proxy.ts در Next.js 16 چگونه کار میکند، سه پروژه را خراب کردم.
خطا بیصدا بود. بدون لاگ. بدون هشدار. بدون خطا. فقط ریدایرکتهای خراب و شکافهای امنیتی.
اگر در حال ارتقا به Next.js 16 هستید، فقط یک codemod اجرا نکنید و تمام. شما باید این سه مورد را بررسی کنید.
تلهی مهاجرت
Next.js نام middleware.ts را به proxy.ts تغییر داد. این فقط یک تغییر نام ساده نیست.
middleware.tsروی Edge runtime اجرا میشد. پشتیبانی محدودی از crypto داشت.proxy.tsبهطور پیشفرض روی Node.js runtime اجرا میشود. از پشتیبانی کامل crypto برخوردار است.
اگر پکیج خود را بدون استفاده از codemod بهصورت دستی بهروزرسانی کنید، ممکن است فایل قدیمی middleware.ts همچنان وجود داشته باشد. این فایل بدون مشکل کامپایل میشود و تستهای TypeScript را هم پاس میکند، اما هیچ کاری انجام نمیدهد. مسیرهای (routes) شما رهگیری نمیشوند و ریدایرکتهای شما اجرا نخواهند شد.
این سه مورد را بهصورت دستی بررسی کنید:
proxy.tsباید در ریشه (root) پروژه شما وجود داشته باشد.- تابع اکسپورت شده (exported function) باید
proxyنام داشته باشد. - فایل
middleware.tsباید حذف شود.
شکاف Matcher
Matcher جایی است که تنظیمات احراز هویت (auth) اغلب در آن با شکست مواجه میشوند.
اگر matcher شما خیلی گسترده (broad) باشد، proxy روی هر فایل CSS و تصویر اجرا میشود. این امر باعث ایجاد حلقههای ریدایرکت بینهایت میشود.
اگر matcher شما خیلی محدود (narrow) باشد، یک حفره امنیتی ایجاد میکنید.
اگر مسیری در matcher شما نباشد، proxy هرگز اجرا نمیشود. کاربر میتواند هدرهای (headers) خود را به آن مسیر ارسال کند. اگر Server Component شما به آن هدرها اعتماد کند، یک مهاجم میتواند خود را به جای هر کسی جا بزند.
راه حل: به هدرها اعتماد نکنید
من این را از راه سخت یاد گرفتم: فقط به هدرهایی که توسط proxy ارسال میشوند، تکیه نکنید.
از یک رویکرد دو لایه استفاده کنید:
- proxy بهعنوان یک دروازه سریع در مرز شبکه عمل میکند.
- Server Component، توکن JWT را مستقیماً از کوکی در زمان رندر (render time) تأیید میکند.
این بررسی دوم، شکاف را میبندد. حتی اگر matcher یک مسیر را از قلم بیندازد، Server Component کاربر نامعتبر را شناسایی میکند. این کار چند میلیثانیه تأخیر (latency) اضافه میکند اما از یک شکست امنیتی بزرگ جلوگیری میکند.
چکلیست خلاصه:
- از
proxy.tsبرای احراز هویت استفاده کنید. - از Node.js runtime برای پشتیبانی کامل از crypto استفاده کنید.
- هدرها را روی request تنظیم کنید، نه روی response.
- همیشه JWT را داخل Server Components تأیید کنید.