PostgreSQL: المستخدمون والأدوار وإدارة الصلاحيات في…

آخر تحديث: 2026-08-26

1. ما ستتعلمه


2. القصة

Charlie هو DBA لمنصة تجارة إلكترونية SaaS ويحتاج إلى تكوين صلاحيات قاعدة البيانات لـ 5 فرق:

الفريق الصلاحيات المطلوبة
dev (التطوير) قراءة/كتابة جميع جداول الأعمال، إنشاء جداول اختبار
analytics (التحليلات) قراءة فقط جميع جداول الأعمال، إنشاء طرق عرض مادية
ops (العمليات) إدارة المستخدمين، مراقبة قاعدة البيانات
audit (التدقيق) قراءة فقط سجلات التدقيق، ليس بيانات الأعمال
app (خدمة التطبيق) قراءة/كتابة جداول الأعمال، لا DDL

يستخدم Charlie توريث الأدوار و RLS لتنفيذ مبدأ الصلاحيات الدنيا.


3. المفهوم: الأدوار والمستخدمين

(1) CREATE ROLE مقابل CREATE USER

الأمر صلاحية LOGIN الشكل المكافئ
CREATE ROLE r1; لا شيء (لا يمكن تسجيل الدخول)
CREATE USER u1; نعم (يمكن تسجيل الدخول) CREATE ROLE u1 LOGIN;

في PG، المستخدمون والأدوار هما نفس المفهوم؛ USER هو مجرد ROLE مع سمة LOGIN.

(2) سمات الدور في لمحة

السمة الوصف صيغة الإنشاء
LOGIN السماح بالاتصال بقاعدة البيانات LOGIN / NOLOGIN
SUPERUSER مستخدم مميز، يتجاوز جميع الصلاحيات SUPERUSER
CREATEDB يمكن إنشاء قواعد بيانات CREATEDB
CREATEROLE يمكن إنشاء/إدارة الأدوار CREATEROLE
INHERIT يرث تلقائياً صلاحيات الأدوار المملوكة INHERIT (افتراضي)
NOINHERIT لا يرث تلقائياً؛ يحتاج SET ROLE NOINHERIT
PASSWORD تعيين كلمة مرور PASSWORD 'xxx'
VALID UNTIL وقت انتهاء صلاحية كلمة المرور VALID UNTIL 'timestamp'

(1) ▶ مثال

SQL
-- أدوار المجموعة (لا يمكنها تسجيل الدخول)
CREATE ROLE dev_team NOINHERIT;
CREATE ROLE analytics_team NOINHERIT;
CREATE ROLE ops_team NOINHERIT;
CREATE ROLE audit_team NOINHERIT;

-- مستخدمو تسجيل الدخول
-- ⚠️ لا ترمز كلمات المرور في الإنتاج؛ استخدم متغيرات البيئة أو مدير أسرار
CREATE USER alice_dev PASSWORD 'SecureP@ss1' IN ROLE dev_team;
CREATE USER bob_dev PASSWORD 'SecureP@ss2' IN ROLE dev_team;
CREATE USER charlie_analyst PASSWORD 'SecureP@ss3' IN ROLE analytics_team;
CREATE USER diana_ops PASSWORD 'SecureP@ss4' IN ROLE ops_team INHERIT;

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

(2) ▶ مثال

SQL
-- إضافة صلاحية CREATEDB لقائد فريق العمليات
ALTER ROLE diana_ops CREATEDB;

-- تعيين انتهاء صلاحية كلمة المرور
ALTER ROLE charlie_analyst VALID UNTIL '2025-12-31';

-- إعادة تسمية دور
ALTER ROLE dev_team RENAME TO engineering_team;

-- تعطيل تسجيل الدخول مؤقتاً
ALTER ROLE bob_dev NOLOGIN;

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

4. المفهوم: صلاحيات GRANT / REVOKE

(1) تسلسل الصلاحيات

100%
flowchart TD
    A[قاعدة البيانات<br/>CONNECT / CREATE / TEMP] --> B[المخطط<br/>CREATE / USAGE]
    B --> C[الجدول<br/>SELECT / INSERT / UPDATE / DELETE / TRUNCATE / REFERENCES / TRIGGER]
    C --> D[العمود<br/>SELECT / INSERT / UPDATE / REFERENCES]
    B --> E[الدالة<br/>EXECUTE]
    B --> F[التسلسل<br/>USAGE / SELECT / UPDATE]
    A --> G[الدور<br/>MEMBER / SET]

    style A fill:#e1f5fe
    style B fill:#bbdefb
    style C fill:#c8e6c9
    style D fill:#fff9c4

(2) الكلمات المفتاحية الشائعة للصلاحيات

الكائن الصلاحيات القابلة للمنح الوصف
DATABASE CONNECT, CREATE, TEMP الاتصال، إنشاء مخطط، جداول مؤقتة
SCHEMA CREATE, USAGE إنشاء كائنات، الوصول إلى الكائنات
TABLE SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER CRUD كامل + مرجع مفتاح خارجي
COLUMN SELECT, INSERT, UPDATE, REFERENCES تحكم على مستوى العمود
FUNCTION EXECUTE استدعاء الدالة
SEQUENCE USAGE, SELECT, UPDATE استخدام التسلسل

(3) ▶ مثال

SQL
-- فريق التطوير: CRUD كامل على جداول الأعمال
GRANT SELECT, INSERT, UPDATE, DELETE ON products TO dev_team;
GRANT SELECT, INSERT, UPDATE, DELETE ON orders TO dev_team;
GRANT SELECT, INSERT, UPDATE, DELETE ON customers TO dev_team;
GRANT SELECT, INSERT, UPDATE, DELETE ON order_items TO dev_team;

-- فريق التحليلات: قراءة فقط
GRANT SELECT ON products TO analytics_team;
GRANT SELECT ON orders TO analytics_team;
GRANT SELECT ON customers TO analytics_team;

-- فريق التدقيق: فقط سجلات التدقيق
GRANT SELECT ON price_audit_log TO audit_team;
GRANT SELECT ON ddl_audit_log TO audit_team;

Output:

TEXT 📖 للعرض فقط
INSERT 0 1

(4) ▶ مثال

SQL
-- فريق التطوي�� يمكنه إنشاء كائنات في مخطط dev
GRANT CREATE, USAGE ON SCHEMA dev TO dev_team;

-- فريق التحليلات يمكن�� الاستخدام لكن ليس الإنشاء في المخطط public
GRANT USAGE ON SCHEMA public TO analytics_team;

-- السماح للتحليلات بإنشاء طرق عرض مادية في مخططهم الخاص
GRANT CREATE, USAGE ON SCHEMA analytics TO analytics_team;

-- خدمة التطبيق تتصل بقاعدة البيانات
GRANT CONNECT ON DATABASE shop_db TO app_service;

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

(5) ▶ مثال

SQL
-- سحب DELETE من فريق التطوير على products
REVOKE DELETE ON products FROM dev_team;

-- سحب جميع الصلاحيات على جدول
REVOKE ALL PRIVILEGES ON orders FROM public;

-- سحب حق إنشاء المخطط
REVOKE CREATE ON SCHEMA dev FROM dev_team;

-- تتالي: سحب والمنح التابعة
REVOKE SELECT ON products FROM analytics_team CASCADE;

Output:

TEXT 📖 للعرض فقط
DELETE 2

(3) GRANT ALL و GRANT SELECT ALL TABLES

الأمر التأثير
GRANT ALL ON t TO r; منح جميع الصلاحيات على الجدول t
GRANT ALL ON SCHEMA s TO r; منح جميع الصلاحيات على المخطط s
GRANT SELECT ON ALL TABLES IN SCHEMA s TO r; منح SELECT على جميع الجداول في المخطط s
GRANT USAGE ON ALL SEQUENCES IN SCHEMA s TO r; منح USAGE على جميع التسلسلات

5. المفهوم: DEFAULT PRIVILEGES

(1) لماذا تحتاج الصلاحيات الافتراضية

GRANT العادي يؤثر فقط على الكائنات الموجودة بالفعل. الجداول المنشأة في المستقبل لن تحصل على الصلاحيات تلقائياً. DEFAULT PRIVILEGES تحل هذا.

الأمر التأثير
ALTER DEFAULT PRIVILEGES IN SCHEMA s GRANT SELECT ON TABLES TO r; الجداول الجديدة في s تمنح تلقائياً
ALTER DEFAULT PRIVILEGES FOR ROLE owner GRANT ... الصلاحيات الافتراضية لمنشئ محدد

(6) ▶ مثال

SQL
-- جميع الجداول المستقبلية في المخطط public قابلة للقراءة من analytics_team
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT ON TABLES TO analytics_team;

-- جميع الجداول المستقبلية المنشأة بواسطة app_service قابلة للكتابة من dev_team
ALTER DEFAULT PRIVILEGES FOR ROLE app_service IN SCHEMA public
  GRANT SELECT, INSERT, UPDATE ON TABLES TO dev_team;

-- جميع التسلسلات المستقبلية في المخطط public
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT USAGE, SELECT ON SEQUENCES TO dev_team;

-- جميع الدوال المستقبلية
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT EXECUTE ON FUNCTIONS TO analytics_team;

Output:

TEXT 📖 للعرض فقط
INSERT 0 1

(7) ▶ مثال

SQL
SELECT
  pg_get_userbyid(defaclrole) AS grantor,
  pg_get_userbyid(defaclnamespace) AS namespace_owner,
  n.nspname AS schema,
  defaclobjtype AS object_type,
  defaclacl AS acl
FROM pg_default_acl d
JOIN pg_namespace n ON n.oid = d.defaclnamespace;

Output:

TEXT 📖 للعرض فقط
 id | name     | value 
----+----------+-------
  1 | example  | 42
(1 row)

6. المفهوم: سياسات أمان مستوى الصفوف (RLS)

(1) كيفية عمل RLS (ميزة PG)

RLS تتيح لك التحكم في الوصول إلى البيانات على مستوى الصف — الأدوار المختلفة ترى صفوفاً مختلفة في نفس الجدول.

الخطوة الأمر الوصف
1. تمكين RLS ALTER TABLE t ENABLE ROW LEVEL SECURITY; تمكين أمان مستوى الصفوف على الجدول
2. إنشاء سياسة CREATE POLICY ... ON t ...; تعريف قاعدة مستوى الصف
3. تجاوز المستخدم المميز SUPERUSER لا يخضع لـ RLS افتراضياً
4. تجاوز مالك الجدول مالك الجدول لا يخضع افتراضياً؛ استخدم FORCE للفرض

(2) أنواع الياسات

نوع السياسة الكلمة المفتاحية الوصف
SELECT FOR SELECT يتحكم في الصفوف المرئية
INSERT FOR INSERT يتحكم في الصفوف القابلة للإدراج
UPDATE FOR UPDATE يتحكم في الصفوف القابلة للتحديث (يشمل BEFORE/AFTER)
DELETE FOR DELETE يتحكم في الصفوف القابلة للحذف
ALL FOR ALL مشتركة عبر جميع العمليات

(8) ▶ مثال

SQL
-- تمكين RLS على جدول orders
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

-- المحللون يمكنهم فقط رؤية الطلبات المكتملة
CREATE POLICY pol_analytics_completed
  ON orders FOR SELECT
  TO analytics_team
  USING (order_status = 'completed');

-- فريق التطوير يمكنه رؤية جميع الصفوف
CREATE POLICY pol_dev_all
  ON orders FOR ALL
  TO dev_team
  USING (true)
  WITH CHECK (true);

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

(9) ▶ مثال

SQL
-- تمكين RLS على جدول customers
ALTER TABLE customers ENABLE ROW LEVEL SECURITY;

-- كل مستخدم خدمة عملاء يرى فقط منطقته المعينة
CREATE POLICY pol_region_access
  ON customers FOR SELECT
  USING (region = current_setting('app.region', true));

-- فرض التزام مالك الجدول أيضاً بـ RLS
ALTER TABLE orders FORCE ROW LEVEL SECURITY;

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

(10) ▶ مثال

SQL
-- فريق المبيعات يمكنه فقط إدراج طلبات في منطقته
CREATE POLICY pol_sales_insert
  ON orders FOR INSERT
  TO dev_team
  WITH CHECK (region = current_setting('app.region', true));

-- فريق المبيعات يمكنه فقط تحديث الطلبات في منطقته
CREATE POLICY pol_sales_update
  ON orders FOR UPDATE
  TO dev_team
  USING (region = current_setting('app.region', true))
  WITH CHECK (region = current_setting('app.region', true));

Output:

TEXT 📖 للعرض فقط
INSERT 0 1

(3) USING مقابل WITH CHECK

العبارة الدور تنطبق على
USING تصفي الصفوف المرئية (WHERE لـ SELECT/UPDATE/DELETE) SELECT/UPDATE/DELETE
WITH CHECK تتحقق مما إذا كان الصف الجديد مسموحاً (القيم الجديدة لـ INSERT/UPDATE) INSERT/UPDATE

7. المفهوم: توريث الأدوار وطرق عرض النظام

(1) INHERIT مقابل NOINHERIT

السمة السلوك السيناريو
INHERIT (افتراضي) يكتسب تلقائياً صلاحيات الأدوار المملوكة المستخدمون العاديون
NOINHERIT يحتاج SET ROLE r لاستخدام الصلاحيات تصعيد مؤقت للصلاحيات، فصل التدقيق

(11) ▶ مثال

SQL
-- إنشاء دور قوي مع NOINHERIT
CREATE ROLE admin_role NOINHERIT;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO admin_role;

-- Diana في admin_role لكن لا يمكنها استخدام صلاحيات المسؤول تلقائياً
CREATE USER diana PASSWORD 'SecureP@ss5' IN ROLE admin_role NOINHERIT;

-- يجب على Diana التبديل صراحةً لاستخدام حقوق المسؤول
SET ROLE admin_role;
-- الآن يمكن لـ diana تنفيذ عمليات المسؤول
RESET ROLE;
-- العودة إلى الصلاحيات العادية

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

(2) طرق عرض النظام

طريقة العرض المحتوى
pg_roles جميع الأدوار وسماتها
pg_auth_members علاقات الدور-العضو
information_schema.role_table_grants صلاحيات مستوى الجدول
information_schema.role_usage_grants صلاحيات المخطط/الدالة

(12) ▶ مثال

SQL
-- سرد جميع الأدوار وسماتها
SELECT rolname, rolsuper, rolcreatedb, rolcanlogin, rolinherit
FROM pg_roles
WHERE rolname NOT LIKE 'pg_%'
ORDER BY rolname;

-- سرد عضوية الأدوار
SELECT
  r1.rolname AS member,
  r2.rolname AS role
FROM pg_auth_members m
JOIN pg_roles r1 ON r1.oid = m.member
JOIN pg_roles r2 ON r2.oid = m.roleid
ORDER BY r2.rolname, r1.rolname;

-- التحقق من صلاحيات الجدول لدور
SELECT table_name, privilege_type
FROM information_schema.role_table_grants
WHERE grantee = 'analytics_team'
ORDER BY table_name, privilege_type;

Output:

TEXT 📖 للعرض فقط
CREATE TABLE

8. مخطط التدفق: قرار تكوين الصلاحيات

100%
flowchart TD
    A[تكوين الصلاحيات] --> B{بحاجة لتحكم على مستوى الصف؟}
    B -->|نعم| C[تمكين RLS<br/>CREATE POLICY]
    B -->|لا| D{دقة الصلاحية؟}
    D -->|جدول كامل| E[GRANT ON TABLE]
    D -->|عمود محدد| F[GRANT column_name ON TABLE]
    D -->|جميع الجداول في المخطط| G[GRANT ALL TABLES IN SCHEMA]
    E --> H{بحاجة لمنح تلقائي على الجداول الجدي��ة؟}
    G --> H
    H -->|نعم| I[ALTER DEFAULT PRIVILEGES]
    H -->|لا| J[GRANT يدوي]
    C --> K{بحاجة لتقييد مالك الجدول أيضاً؟}
    K -->|نعم| L[FORCE ROW LEVEL SECURITY]
    K -->|لا| M[المالك يتجاوز RLS افتراضياً]
    I --> N{المستخدم بحاجة لتصعيد مؤقت؟}
    J --> N
    N -->|نعم| O[NOINHERIT + SET ROLE]
    N -->|لا| P[INHERIT افتراضياً]

    style C fill:#fff9c4
    style I fill:#c8e6c9
    style O fill:#ffcdd2

9. مثال شامل

يقوم Charlie بتكوين نظام صلاحيات كامل للفرق الخمسة:

SQL
-- الخطوة 1: إنشاء أدوار المجموعة
CREATE ROLE dev_team NOINHERIT;
CREATE ROLE analytics_team NOINHERIT;
CREATE ROLE ops_team INHERIT;
CREATE ROLE audit_team NOINHERIT;
CREATE ROLE app_service LOGIN PASSWORD 'AppSecRet!';

-- الخطوة 2: منح صلاحيات المخطط
GRANT CREATE, USAGE ON SCHEMA public TO dev_team;
GRANT USAGE ON SCHEMA public TO analytics_team;
GRANT CREATE, USAGE ON SCHEMA analytics TO analytics_team;
GRANT USAGE ON SCHEMA public TO ops_team;
GRANT USAGE ON SCHEMA audit TO audit_team;

-- الخطوة 3: منح صلاحيات الجدول
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO dev_team;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO analytics_team;
GRANT SELECT ON ALL TABLES IN SCHEMA audit TO audit_team;
GRANT SELECT, INSERT, UPDATE, DELETE ON products, orders, order_items, customers TO app_service;

-- الخطوة 4: الصلاحيات الافتراضية للجداول المستقبلية
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT ON TABLES TO analytics_team;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO dev_team;
ALTER DEFAULT PRIVILEGES IN SCHEMA audit
  GRANT SELECT ON TABLES TO audit_team;

-- الخطوة 5: صلاحيات التسلسلات والدوال
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO dev_team;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app_service;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
  GRANT USAGE, SELECT ON SEQUENCES TO dev_team;

-- الخطوة 6: RLS - المحللون يرون فقط الطلبات المكتملة
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY pol_analytics_orders
  ON orders FOR SELECT
  TO analytics_team
  USING (order_status = 'completed');

-- الخطوة 7: RLS - فريق التدقيق يرى فقط مخطط audit
ALTER TABLE price_audit_log ENABLE ROW LEVEL SECURITY;
CREATE POLICY pol_audit_read
  ON price_audit_log FOR SELECT
  TO audit_team
  USING (true);

-- الخطوة 8: إنشاء مستخدمي تسجيل الدخول وتعيين الأدوار
CREATE USER alice_dev PASSWORD 'DevP@ss1' IN ROLE dev_team;
CREATE USER bob_dev PASSWORD 'DevP@ss2' IN ROLE dev_team;
CREATE USER charlie_analyst PASSWORD 'AnlP@ss3' IN ROLE analytics_team;
CREATE USER diana_ops PASSWORD 'OpsP@ss4' IN ROLE ops_team CREATEROLE;
CREATE USER eve_audit PASSWORD 'AudP@ss5' IN ROLE audit_team;

❓ أسئلة شائعة

س ما الفرق بين CREATE USER و CREATE ROLE؟
ج CREATE USER مكافئ لـ CREATE ROLE ... LOGIN. في PG، المستخدمون والأدوار هما نفس المفهوم؛ USER هو مجرد دور يحمل سمة LOGIN افتراضياً.
س هل GRANT SELECT ON ALL TABLES يشمل الجداول المنشأة في المستقبل؟
ج لا. ALL TABLES يمنح فقط للجداول الموجودة حالياً. الجداول المستقبلية تحتاج ALTER DEFAULT PRIVILEGES للمنح التلقائي أو GRANT يدوي.
س هل RLS تؤثر على المستخدمين المميزين؟
ج ليس افتراضياً. SUPERUSER يتجاوز جميع سياسات RLS. لفرضها، استخدم ALTER TABLE ... FORCE ROW LEVEL SECURITY، لكن هذا ينطبق فقط على مالك الجدول — SUPERUSER لا يزال يتجاوز.
س كيف يحصل دور NOINHERIT على الصلاحيات مؤقتاً؟
ج استخدم SET ROLE target_role للتبديل إلى الدور الهدف واكتساب صلاحياته؛ بعد الانتهاء، RESET ROLE يستعيد الصلاحيات الأصلية. SET ROLE يؤثر فقط على الجلسة الحالية.
س هل REVOKE يحتاج CASCADE؟
ج إذا كانت الصلاحية المسحوبة قد منحت بدورها لدور آخر (منح تابع)، تحتاج CASCADE لسحبها كلها مرة واحدة. RESTRICT الافتراضي سيخطئ عندما يكون هناك تبعية.
س كيف أعرض الصلاحيات التي يمتلكها المستخدم فعلياً؟
ج استعلم طريقة العرض information_schema.role_table_grants، أو استخدم أوامر psql \dp و \du+. لاحظ أن أدوار INHERIT تكتسب تلقائياً صلاحيات الأدوار التي تنتمي إليها.
س هل يمكن كتابة USING و WITH CHECK في RLS بشكل منفصل؟
ج نعم. إذا كتبت USING فقط، WITH CHECK افتراضياً نفس USING. لسياسة ALL، يوصى بكتابة كليهما صراحةً لجعل التحكم واضحاً.
س ماذا لو كانت USAGE على المخطط غير كافية للوصول إلى جدول؟
ج USAGE فقط تسمح لك بـ "الدخول" إلى المخطط ورؤية قائمة الكائنات؛ تحتاج أيضاً صلاحية مثل SELECT على الجدول المحدد. كلا طبقتي الصلاحية يجب أن تتحققا.

📖 ملخص


📝 تمارين

  1. ⭐ أنشئ دور readonly ومستخدماً report_user، امنح readonly صلاحية SELECT على جميع الجداول في المخطط public، وعيّن الصلاحيات الافتراضية بحيث تمنح الجداول المنشأة حديثاً تلقائياً.

  2. ⭐⭐ فعّل RLS على جدول orders وأنشئ سياسات: sales_team يمكنه فقط رؤية الطلبات في منطقته (region = current_setting('app.region')audit_team يمكنه فقط رؤية الطلبات مع order_status = 'completed'.

  3. ⭐⭐⭐ صمم نظام صلاحيات كامل: أنشئ 3 أدوار مجموعة (backend_dev، data_analyst، db_admin)، مانحاً كل منها مستويات مختلفة من الصلاحيات (مخطط/جدول/عمود/دالة/تسلسل)، اضبط DEFAULT PRIVILEGES، امنح عمود salary بشكل منفصل (المحلل لا يمكنه رؤيته)، واستخدم pg_roles و information_schema للاستعلام والتحقق من نتيجة التكوين.

Web-Tutorial.com

فريق Web-Tutorial التقني

منصة دروس برمجية يديرها عدة مطورين. كل درس يتم كتابته ومراجعته بواسطة مطورين متخصصين في المجال. نعمل على ضمان دقة وموثوقية المحتوى — إذا لاحظت أي مشكلة، فيرجى إخبارنا.

100%