سياسات الأمان على مستوى الصفوف
رشّح الصفوف تلقائيًا لكل مستخدم
سياسات الأمان على مستوى الصفوف درس مجاني في SQL Academy على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في SQL Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة SQL Academy 4 دروس في المجموع.
ما الأمان على مستوى الصفوف؟
الأمان على مستوى الصفوف (RLS) هو ميزة في PostgreSQL تتيح لك التحكم في الصفوف التي يستطيع مستخدم أو دور معين في قاعدة البيانات رؤيتها أو تعديلها. وبدلًا من تصفية الصفوف في كل استعلام، تعرّف سياسة مرة واحدة، ثم يفرضها PostgreSQL تلقائيًا على كل عمليات SELECT وINSERT وUPDATE وDELETE.
فكّر فيه على أنه جملة WHERE غير مرئية مرفقة بالجدول نفسه، لا باستعلام محدد.
تمكين RLS على جدول
يكون RLS معطّلًا افتراضيًا. ويجب تمكينه صراحةً لكل جدول باستخدام ALTER TABLE ... ENABLE ROW LEVEL SECURITY. وبعد تمكينه، لن يرى أي دور ليس مالك الجدول أي صفوف إلى أن تُنشأ سياسة واحدة على الأقل.
-- Create a sample table
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
owner TEXT NOT NULL,
amount NUMERIC(10,2)
);
-- Enable RLS
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;إنشاء سياستك الأولى
تُنشأ السياسة باستخدام CREATE POLICY. وتمنحها اسمًا، وتحدد الجدول، وتقدم تعبير USING. وعبارة USING هي تعبير منطقي يُقيَّم لكل صف؛ ولا تكون الصفوف مرئية للمستخدم إلا إذا أعاد التعبير القيمة TRUE.
-- Allow each user to see only their own orders
CREATE POLICY orders_owner_policy
ON orders
FOR SELECT
USING (owner = current_user);عبارتا USING وWITH CHECK
تتضمن السياسات عبارتي تصفية تؤديان غرضين مختلفين:
- USING — تصفي الصفوف في عمليات القراءة (SELECT, UPDATE, DELETE). لا يكون الصف مرئيًا إلا إذا أعادت USING القيمة TRUE.
- WITH CHECK — تتحقق من صحة الصفوف في عمليات الكتابة (INSERT, UPDATE). لا يُسمح بالكتابة إلا إذا أعادت WITH CHECK القيمة TRUE. وإذا حُذفت، يُعاد استخدام USING للتحقق من عمليات الكتابة.
-- Allow users to select and insert only their own rows
CREATE POLICY orders_isolation
ON orders
FOR ALL
USING (owner = current_user)
WITH CHECK (owner = current_user);نطاق السياسة: FOR SELECT وINSERT وUPDATE وDELETE
يمكن لسياسة واحدة أن تغطي جميع الأوامر (FOR ALL) أو أمرًا محددًا. ويمنح فصل السياسات حسب الأمر تحكمًا دقيقًا — مثل السماح لكل مستخدم بقراءة جميع الصفوف، مع السماح له بتعديل صفوفه فقط.
-- Everyone can read all orders
CREATE POLICY read_all_orders
ON orders
FOR SELECT
USING (true);
-- But each user can only update their own orders
CREATE POLICY update_own_orders
ON orders
FOR UPDATE
USING (owner = current_user)
WITH CHECK (owner = current_user);استخدام session_user وcurrent_user
توفر PostgreSQL دوال مضمّنة لتحديد المستخدم النشط داخل تعبير السياسة:
- current_user — الدور الذي تكون صلاحياته مفعّلة حاليًا، وقد يتغير بعد استخدام SET ROLE.
- session_user — الدور الذي فتح الاتصال، ولا يتغير أثناء الجلسة.
تعتمد معظم سياسات RLS على current_user لأنه يعكس الدور الفعّال بعد تبديل الأدوار.
-- Inspect the current identity inside a query
SELECT current_user, session_user;تطبيق RLS على أدوار محددة
تُطبَّق السياسة افتراضيًا على PUBLIC، أي على جميع الأدوار. ويمكنك تقييدها بدور محدد باستخدام عبارة TO. ويفيد ذلك عندما تريد سياسة للمستخدمين العاديين وأخرى لدور المسؤول.
-- Policy only for the 'app_user' role
CREATE POLICY app_user_policy
ON orders
FOR SELECT
TO app_user
USING (owner = current_user);
-- Separate permissive policy for 'admin' role
CREATE POLICY admin_full_access
ON orders
FOR ALL
TO admin
USING (true)
WITH CHECK (true);السياسات PERMISSIVE مقابل RESTRICTIVE
يمكن أن تتفاعل السياسات المتعددة على الجدول نفسه بطريقتين:
- PERMISSIVE (الافتراضية) — تُجمع جميع السياسات PERMISSIVE باستخدام OR. ويمكن الوصول إلى الصف إذا سمحت به أي سياسة PERMISSIVE.
- RESTRICTIVE — تُجمع السياسات RESTRICTIVE باستخدام AND مع نتيجة السياسات PERMISSIVE. ولا يمكن الوصول إلى الصف إلا إذا اجتاز السياسة RESTRICTIVE وسمحت به سياسة PERMISSIVE واحدة على الأقل.
-- Restrictive policy: block access to archived orders for everyone
CREATE POLICY no_archived_rows
ON orders
AS RESTRICTIVE
FOR SELECT
USING (amount > 0);تجاوز RLS: BYPASSRLS ومالكو الجداول
يتجاوز مالك الجدول والمستخدمون المتميزون RLS افتراضيًا، ويمكنهم دائمًا رؤية جميع الصفوف. ويمكنك منح الدور السمة BYPASSRLS إذا احتاج إلى وصول غير مقيّد من دون أن يكون مستخدمًا متميزًا. وعلى العكس، يمكنك إلزام المالك بتطبيق RLS باستخدام FORCE ROW LEVEL SECURITY.
-- Force the table owner to also obey RLS policies
ALTER TABLE orders FORCE ROW LEVEL SECURITY;
-- Grant BYPASSRLS to a trusted service account
ALTER ROLE service_account BYPASSRLS;تعديل السياسات وحذفها
يمكنك تعديل سياسة موجودة باستخدام ALTER POLICY أو إزالتها بالكامل باستخدام DROP POLICY. ويعني حذف جميع السياسات مع بقاء RLS مفعّلًا أنه لا يمكن للأدوار غير المالكة الوصول إلى أي صفوف. ولإزالة RLS بالكامل، عطّله باستخدام ALTER TABLE.
-- Rename a policy
ALTER POLICY orders_owner_policy ON orders
RENAME TO user_isolation_policy;
-- Update the USING expression
ALTER POLICY user_isolation_policy ON orders
USING (owner = current_user AND amount >= 0);
-- Remove a policy
DROP POLICY admin_full_access ON orders;
-- Disable RLS entirely on the table
ALTER TABLE orders DISABLE ROW LEVEL SECURITY;نمط عملي: عزل البيانات متعددة المستأجرين
من الأنماط الشائعة في تطبيقات SaaS متعددة المستأجرين تخزين عمود tenant_id في كل جدول، واستخدام متغير على مستوى الجلسة (set_config) لتمرير معرّف المستأجر عند إنشاء الاتصال. ثم تقارن السياسة قيمة tenant_id لكل صف بهذا الإعداد.
-- Table with tenant isolation column
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
tenant_id TEXT NOT NULL,
title TEXT
);
ALTER TABLE documents ENABLE ROW LEVEL SECURITY;
-- Policy reads the tenant from a session variable
CREATE POLICY tenant_isolation
ON documents
FOR ALL
USING (tenant_id = current_setting('app.tenant_id'))
WITH CHECK (tenant_id = current_setting('app.tenant_id'));
-- Application sets the variable before running queries
SELECT set_config('app.tenant_id', 'tenant_42', true);
-- Now only tenant_42 documents are visible
SELECT * FROM documents;اختبار المعرفة
اختبر مدى فهمك لسياسات أمان مستوى الصفوف في PostgreSQL.
مراجعة الدرس
في هذا الدرس تعلّمت كيف يوفّر أمان مستوى الصفوف تصفية تلقائية للصفوف، تتحكم فيها السياسات مباشرة على مستوى قاعدة البيانات:
- تمكين RLS على جدول باستخدام ALTER TABLE ... ENABLE ROW LEVEL SECURITY.
- استخدام CREATE POLICY مع عبارة USING لتصفية الصفوف القابلة للقراءة، وعبارة WITH CHECK للتحقق من الصفوف المكتوبة.
- تقييد نطاق السياسات بأوامر محددة (SELECT, INSERT, UPDATE, DELETE, ALL) وأدوار محددة باستخدام عبارة TO.
- دمج سياسات PERMISSIVE (منطق OR) وسياسات RESTRICTIVE (منطق AND) لتوفير تحكم متعدد الطبقات في الوصول.
- يتجاوز مالكو الجداول والمستخدمون المتميزون RLS افتراضيًا؛ استخدم FORCE ROW LEVEL SECURITY لتغيير ذلك.
- يُعد نمط تعدد المستأجرين باستخدام current_setting() تطبيقًا عمليًا قويًا لـ RLS.
يُعد RLS الطريقة القياسية لفرض عزل البيانات بوضوح واتساق، من دون نثر عبارات WHERE في كل استعلام من استعلامات التطبيق.
الأسئلة الشائعة
هل درس «سياسات الأمان على مستوى الصفوف» مجاني؟
نعم — نص درس «سياسات الأمان على مستوى الصفوف» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة SQL Academy، انتقل إلى CoddyKit PRO. تتضمن دورة SQL Academy 4 دروس في المجموع.
ماذا ستتعلم في «سياسات الأمان على مستوى الصفوف»؟
رشّح الصفوف تلقائيًا لكل مستخدم تتمرن على SQL Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ SQL Academy؟
لا تُشترط خبرة سابقة. SQL Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «سياسات الأمان على مستوى الصفوف»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس SQL Academy هذا؟
نعم. كل درس في SQL Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- الأدوار والامتيازات
- سياسات الأمان على مستوى الصفوف
- الأذونات على مستوى الأعمدة
- تدقيق الوصول