Next.js
قراءة في 8 دقائقالمصادقة ليست التفويض: تأمين تطبيق Next.js
ابنِ تصورًا أمنيًا للجلسات والأدوار وإجراءات الخادم ومعالجات المسارات والوصول إلى قاعدة البيانات.

تجيب المصادقة عن سؤال «من يرسل هذا الطلب؟» بينما يجيب التفويض عن سؤال «هل يُسمح لهذه الهوية بتنفيذ هذا الإجراء على هذا المورد؟». تسجيل الدخول لا يمنح المستخدم تلقائيًا حق قراءة كل سجل أو تنفيذ كل تعديل.
تجيب المصادقة عن سؤال «من يرسل هذا الطلب؟» بينما يجيب التفويض عن سؤال «هل يُسمح لهذه الهوية بتنفيذ هذا الإجراء على هذا المورد؟». تسجيل الدخول لا يمنح المستخدم تلقائيًا حق قراءة كل سجل أو تنفيذ كل تعديل.
إدارة الجلسات
استخدم مكتبة مصادقة مُصانة لإنشاء الجلسات وتدويرها وانتهائها وإدارة ملفات الارتباط. اجعل ملفات ارتباط الجلسة HttpOnly وSecure في الإنتاج، واختر سياسة SameSite المناسبة لتدفق تسجيل الدخول. لا تخزن الأسرار طويلة الأمد في localStorage ولا تكشف مفاتيح الخادم ضمن حزمة العميل.
فرض التفويض على الخادم
تحقق من الصلاحيات عند حد الخادم الذي ينفذ العملية. إخفاء رابط الإدارة أو تعطيل زر يحسن الواجهة لكنه ليس فحص صلاحيات. يجب على كل Server Action وRoute Handler التحقق من الجلسة الحالية والمورد المطلوب.
إنشاء حارس قابل لإعادة الاستخدام
import { auth } from '@/lib/auth';
import { headers } from 'next/headers';
import { redirect } from 'next/navigation';
export async function requireAdmin() {
const session = await auth.api.getSession({ headers: await headers() });
if (!session) redirect('/login');
if (session.user.role !== 'admin') redirect('/unauthorized');
return session.user;
}يجعل الحارس المشترك سياسة الوصول واضحة. تعتمد واجهة الجلسة الدقيقة ونموذج الأدوار على إعداد المصادقة لديك؛ اعتبر المثال نمطًا وعدّله ليتوافق مع إصدار Better Auth وأنواع التطبيق.
حماية كل تعديل
'use server';
export async function deleteUser(userId: string) {
const actor = await requireAdmin(); // Never trust a role sent by the browser
if (actor.id === userId) throw new Error('Cannot delete your own account');
await db.user.delete({ where: { id: userId } });
return { success: true };
}استدعِ الحارس داخل كل تعديل حساس، لا في الصفحة التي تربط به فقط. يمكن للمستخدم استدعاء Server Action مباشرة. تحقق أيضًا من المورد المستهدف؛ ففحص الدور وحده لا يمنع تعديل سجل مستخدم آخر إذا غابت قواعد الملكية.
استخدام ثوابت قاعدة البيانات
استخدم قيود قاعدة البيانات للثوابت التي يجب أن تبقى صحيحة حتى عند وجود خطأ في التطبيق، مثل البريد الفريد والمفاتيح الخارجية والعلاقات الصحيحة. في التطبيقات متعددة المستأجرين، قيد الاستعلامات بالمستأجر وملكية المورد بدل جلب البيانات عالميًا والاعتماد على الواجهة لتصفيتها.
حماية التدفقات المحيطة
راجع حماية CSRF وحدود محاولات تسجيل الدخول وOTP وانتهاء صلاحية رموز إعادة تعيين كلمة المرور ورسائل الخطأ العامة التي لا تكشف وجود الحساب. سجل الأحداث الأمنية دون تسجيل كلمات المرور أو الرموز الخام أو ملفات الجلسة كاملة.
قائمة لاتخاذ القرار
اختبر الوصول دون تسجيل دخول، ومحاولة مستخدم عادي تنفيذ إجراء إداري، وطلب مورد مستخدم آخر، والجلسات المنتهية والطلبات المتكررة. الأمن خاص بمسار البيانات على الخادم وليس بمظهر الواجهة.