นโยบายความปลอดภัยระดับแถว
กรองแถวตามผู้ใช้โดยอัตโนมัติ
นโยบายความปลอดภัยระดับแถว เป็นบทเรียน SQL Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 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);การใช้ผู้ใช้เซสชันและ current_user
PostgreSQL มีฟังก์ชันในตัวสำหรับระบุผู้ใช้ที่กำลังใช้งานอยู่ภายในนิพจน์ของนโยบาย:
- current_user — บทบาทที่กำลังใช้สิทธิ์อยู่ในขณะนั้น (อาจเปลี่ยนแปลงได้หลัง SET ROLE)
- ผู้ใช้เซสชัน — บทบาทที่เปิดการเชื่อมต่อ (จะไม่เปลี่ยนแปลงตลอดเซสชัน)
นโยบาย 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 ให้บทบาทหนึ่งได้ หากบทบาทนั้นต้องการ access แบบไม่จำกัดโดยไม่ต้องเป็นผู้ใช้ระดับสูงสุด ในทางกลับกัน คุณสามารถบังคับให้เจ้าของตารางปฏิบัติตาม 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;รูปแบบการใช้งานจริง: การแยกข้อมูลของผู้เช่าหลายราย
รูปแบบ RLS ที่ใช้กันทั่วไปในแอป SaaS แบบหลายผู้เช่าคือการเพิ่มคอลัมน์ รหัสผู้เช่า ในทุกตาราง และใช้ตัวแปรระดับเซสชัน (set_config) เพื่อส่งตัวระบุผู้เชื่อมต่อในขณะเชื่อมต่อ จากนั้นนโยบายจะเปรียบเทียบรหัสผู้เช่าของแต่ละแถวกับค่าดังกล่าว
-- 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 ช่วยกรองแถวโดยอัตโนมัติตามนโยบายโดยตรงที่ระดับฐานข้อมูลได้อย่างไร:
- เปิดใช้ RLS ในตารางด้วย ALTER TABLE ... ENABLE ROW LEVEL SECURITY
- ใช้ CREATE POLICY ร่วมกับเงื่อนไข USING เพื่อกรองแถวที่อ่านได้ และเงื่อนไข WITH CHECK เพื่อตรวจสอบแถวที่เขียน
- กำหนดขอบเขตของนโยบายให้กับคำสั่งเฉพาะ (SELECT, INSERT, UPDATE, DELETE, ALL) และบทบาทเฉพาะโดยใช้อนุประโยค TO
- ผสมนโยบาย PERMISSIVE (ตรรกะ OR) และ RESTRICTIVE (ตรรกะ AND) เพื่อสร้างการควบคุม access แบบหลายชั้น
- เจ้าของตารางและผู้ใช้ระดับสูงสุดจะข้าม RLS ได้โดยค่าเริ่มต้น ให้ใช้ FORCE ROW LEVEL SECURITY เพื่อบังคับใช้ RLS กับบุคคลเหล่านี้
- รูปแบบหลายผู้เช่าที่ใช้ current_setting() เป็นการประยุกต์ใช้ RLS ในโลกจริงที่ทรงพลัง
RLS เป็นวิธีมาตรฐานในการบังคับใช้การแยกข้อมูลอย่างเป็นระเบียบและสม่ำเสมอ โดยไม่ต้องกระจายเงื่อนไข WHERE ไปทั่วทุกคำสั่งสอบถามของแอปพลิเคชัน
เรียนรู้ SQL ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 46
- บทเรียน
- 183
คำถามที่พบบ่อย
บทเรียน “นโยบายความปลอดภัยระดับแถว” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “นโยบายความปลอดภัยระดับแถว” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส SQL Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส SQL Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “นโยบายความปลอดภัยระดับแถว”
กรองแถวตามผู้ใช้โดยอัตโนมัติ คุณปฏิบัติ SQL Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน SQL Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน SQL Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “นโยบายความปลอดภัยระดับแถว” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน SQL Academy นี้ได้ไหม
ได้ บทเรียน SQL Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- บทบาทและสิทธิ์
- นโยบายความปลอดภัยระดับแถว
- สิทธิ์ระดับคอลัมน์
- การตรวจสอบการเข้าถึง