สิทธิ์ระดับคอลัมน์
ซ่อนคอลัมน์ที่มีข้อมูลละเอียดอ่อน
สิทธิ์ระดับคอลัมน์ เป็นบทเรียน SQL Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน SQL Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส SQL Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดสิทธิ์ระดับคอลัมน์จึงสำคัญ
ผู้ใช้ทุกคนไม่ควรมองเห็นทุกคอลัมน์ในตารางเดียวกัน คอลัมน์ เงินเดือน แฮชรหัสผ่าน หรือ หมายเลขบัตรเครดิต อาจอยู่ในตารางเดียวกับข้อมูลที่เปิดเผยได้ทั่วไป เช่น ชื่อผู้ใช้หรืออีเมล
สิทธิ์ระดับคอลัมน์ช่วยให้คุณมอบ access ให้เฉพาะคอลัมน์ที่กำหนดแทนการมอบให้ทั้งตาราง ทำให้ข้อมูลอ่อนไหวยังคงถูกซ่อนไว้จากผู้ใช้ที่ไม่มีเหตุผลด้านงานต้องเห็นข้อมูลเหล่านั้น
GRANT กับทั้งตาราง
โดยค่าเริ่มต้น GRANT SELECT ON table จะให้บทบาทนั้นอ่านได้ทุกคอลัมน์ การทำเช่นนี้เหมาะกับข้อมูลสาธารณะ แต่ก่อให้เกิดปัญหาเมื่อตารางมีทั้งคอลัมน์ที่อ่อนไหวและไม่อ่อนไหวปะปนกัน
คำสั่งสอบถามด้านล่างให้บทบาท analyst อ่านตาราง employees ได้ทั้งหมด รวมถึงเงินเดือนและ SSN
GRANT SELECT ON employees TO analyst;ไวยากรณ์ GRANT ระดับคอลัมน์
PostgreSQL (รวมถึงภาษาสอบถามมาตรฐาน) อนุญาตให้ระบุชื่อคอลัมน์เฉพาะภายในคำสั่ง GRANT ได้ ไวยากรณ์คือ:
GRANT privilege (col1, col2) ON table TO role;
ตัวอย่างด้านล่างมอบสิทธิ์ให้บทบาท analyst อ่านได้เฉพาะ id name และ department — แต่ไม่ใช่ salary หรือ ssn
GRANT SELECT (id, name, department) ON employees TO analyst;การตรวจสอบสิทธิ์ระดับคอลัมน์
คุณสามารถตรวจสอบสิทธิ์ระดับคอลัมน์ใน PostgreSQL ได้โดยสอบถามมุมมอง information_schema.column_privileges มุมมองนี้จะแสดงว่าผู้รับสิทธิ์รายใดมีสิทธิ์ใดในคอลัมน์ใด
SELECT grantee, table_name, column_name, privilege_type
FROM information_schema.column_privileges
WHERE table_name = 'employees'
ORDER BY grantee, column_name;จะเกิดอะไรขึ้นหากไม่มีคอลัมน์ที่มีสิทธิ์
หากบทบาทพยายามอ่านคอลัมน์ที่ไม่ได้รับสิทธิ์ ฐานข้อมูลจะแสดงข้อผิดพลาด ไม่อนุญาตให้ใช้สิทธิ์ การอ้างอิงเฉพาะคอลัมน์ที่ได้รับอนุญาตเท่านั้นจึงจะสำเร็จ
สมมติว่า analyst ได้รับสิทธิ์เฉพาะ id name และ department คำสั่งสอบถามแรกด้านล่างจะล้มเหลว ส่วนคำสั่งที่สองจะสำเร็จ
-- This will fail for analyst (no permission on salary):
-- SELECT id, name, salary FROM employees;
-- This succeeds:
SELECT id, name, department FROM employees;สิทธิ์ UPDATE ระดับคอลัมน์
ข้อจำกัดระดับคอลัมน์มีผลกับ UPDATE ด้วย คุณสามารถอนุญาตให้บทบาทแก้ไขได้เฉพาะคอลัมน์ที่กำหนด เช่น อนุญาตให้บทบาทฝ่ายช่วยเหลือแก้ไข status ของผู้ใช้ได้ โดยไม่สามารถเปลี่ยน email หรือ password_hash ของผู้ใช้
GRANT UPDATE (status) ON users TO helpdesk;
-- helpdesk can now run:
UPDATE users SET status = 'suspended' WHERE id = 42;การซ่อนคอลัมน์ด้วยมุมมอง
อีกแนวทางที่ใช้กันทั่วไปคือสร้าง มุมมอง ที่เปิดเผยเฉพาะคอลัมน์ที่ปลอดภัย แล้วมอบ access ให้มุมมองแทนตารางต้นทาง วิธีนี้ใช้ได้กับฐานข้อมูลทั้งหมด ไม่ใช่เฉพาะฐานข้อมูลที่รองรับ GRANT ระดับคอลัมน์
CREATE VIEW public_employees AS
SELECT id, name, department, hire_date
FROM employees;
GRANT SELECT ON public_employees TO analyst;การเพิกถอน access ระดับคอลัมน์
เช่นเดียวกับ GRANT คุณสามารถใช้ REVOKE ร่วมกับรายการคอลัมน์เพื่อนำ access ของคอลัมน์เฉพาะออกได้ หากบทบาทมี access ระดับตารางแบบกว้างอยู่แล้ว คุณอาจต้องเพิกถอน access นั้นทั้งหมดก่อน แล้วจึงมอบ access ระดับคอลัมน์แบบจำกัด
-- Remove all SELECT on the table first
REVOKE SELECT ON employees FROM analyst;
-- Then grant only safe columns
GRANT SELECT (id, name, department) ON employees TO analyst;การใช้สิทธิ์ระดับคอลัมน์ร่วมกับ RLS
สิทธิ์ระดับคอลัมน์และ RLS เป็นกลไกที่เสริมกัน RLS ควบคุมว่า ผู้ใช้จะมองเห็น แถวใด ส่วนสิทธิ์ระดับคอลัมน์ควบคุมว่า ในแถวเหล่านั้นจะมองเห็น คอลัมน์ใด
เมื่อนำมาใช้ร่วมกัน ทั้งสองอย่างจะสร้างการควบคุม access แบบสองมิติที่ทรงพลัง นั่นคือจำกัดชุดแถว และซ่อนข้อมูลสำคัญภายในแต่ละแถว
-- RLS policy: employees can see only their own row
CREATE POLICY own_row ON employees
FOR SELECT
USING (user_id = current_user_id());
-- Column grant: hide salary even for own row
GRANT SELECT (id, name, department) ON employees TO employee_role;การใช้ฟังก์ชัน SECURITY DEFINER
เมื่อคุณต้องการตรรกะที่ละเอียดกว่าการระบุรายการคอลัมน์แบบง่าย ฟังก์ชัน SECURITY DEFINER สามารถทำหน้าที่เป็นตัวเชื่อมได้ ฟังก์ชันจะทำงานด้วยสิทธิ์ของเจ้าของ ซึ่งมี access เต็มรูปแบบสำหรับทุกคอลัมน์ และส่งคืนเฉพาะข้อมูลที่ฟังก์ชันเลือกเปิดเผย ไม่ว่าผู้ใดจะเป็นผู้เรียกใช้
CREATE OR REPLACE FUNCTION get_employee_summary(emp_id INT)
RETURNS TABLE(id INT, name TEXT, department TEXT)
SECURITY DEFINER
LANGUAGE sql AS
$$
SELECT id, name, department
FROM employees
WHERE id = emp_id;
$$;
GRANT EXECUTE ON FUNCTION get_employee_summary(INT) TO analyst;แนวทางการออกแบบเชิงปฏิบัติ: การรักษาความปลอดภัยคอลัมน์แบบหลายชั้น
รูปแบบที่เหมาะกับระบบใช้งานจริงประกอบด้วยสามชั้น:
- การเป็นเจ้าของตาราง — เฉพาะบัญชีบริการของแอปพลิเคชันเท่านั้นที่เป็นเจ้าของตารางต้นทาง
- มุมมองหรือ GRANT ระดับคอลัมน์ — บทบาทสำหรับการอ่านจะเข้าถึงได้เฉพาะคอลัมน์ที่ไม่อ่อนไหว
- คอลัมน์สำหรับตรวจสอบ — บันทึกว่าผู้ใช้รายใดและเวลาใดเข้าถึงข้อมูลอ่อนไหวผ่านทริกเกอร์
วิธีนี้ช่วยให้มั่นใจได้ว่า แม้บทบาทจะได้รับสิทธิ์มากเกินไปโดยไม่ตั้งใจในชั้นหนึ่ง ชั้นอื่น ๆ ก็ยังคงปกป้องข้อมูลไว้
-- Layer 1: revoke public access
REVOKE ALL ON employees FROM PUBLIC;
-- Layer 2: expose safe columns via view
CREATE VIEW employee_public AS
SELECT id, name, department, hire_date FROM employees;
GRANT SELECT ON employee_public TO reporting_role;
-- Layer 3: audit trigger logs sensitive field reads (pseudocode)
-- CREATE TRIGGER audit_salary AFTER SELECT ON employees ...ตรวจสอบอย่างรวดเร็ว
คำสั่ง SQL ใดมอบความสามารถให้บทบาท hr_viewer อ่านได้เฉพาะคอลัมน์ name และ department ของตาราง employees อย่างถูกต้อง
สรุป: สิทธิ์ระดับคอลัมน์
สิทธิ์ระดับคอลัมน์ช่วยให้คุณจำกัด access ให้กับแต่ละคอลัมน์แทนทั้งตาราง ทำให้ข้อมูลอ่อนไหว เช่น เงินเดือน หมายเลขประกันสังคม และแฮชรหัสผ่าน ยังคงถูกซ่อนไว้จากบทบาทที่ไม่มีสิทธิ์
ประเด็นสำคัญ:
- ใช้
GRANT SELECT (col1, col2) ON table TO roleเพื่อจำกัดคอลัมน์ที่อ่านได้ - ใช้
REVOKEร่วมกับรายการคอลัมน์เพื่อนำ access ของคอลัมน์เฉพาะออก - มุมมองเป็นทางเลือกที่ใช้ได้กับฐานข้อมูลต่าง ๆ
- ใช้สิทธิ์ระดับคอลัมน์ร่วมกับ RLS เพื่อสร้างการควบคุม access แบบสองมิติ
- ฟังก์ชัน SECURITY DEFINER ช่วยกรองคอลัมน์ตามโปรแกรมพร้อมตรรกะเพิ่มเติม
เมื่อใช้อย่างสม่ำเสมอ การรักษาความปลอดภัยระดับคอลัมน์เป็นหนึ่งในวิธีที่ง่ายและมีประสิทธิภาพที่สุดในการบังคับใช้หลักการให้สิทธิ์เท่าที่จำเป็นในระดับข้อมูล
คำถามที่พบบ่อย
บทเรียน “สิทธิ์ระดับคอลัมน์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “สิทธิ์ระดับคอลัมน์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส SQL Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส SQL Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “สิทธิ์ระดับคอลัมน์”
ซ่อนคอลัมน์ที่มีข้อมูลละเอียดอ่อน คุณปฏิบัติ SQL Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน SQL Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน SQL Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน
บทเรียน “สิทธิ์ระดับคอลัมน์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน SQL Academy นี้ได้ไหม
ได้ บทเรียน SQL Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- บทบาทและสิทธิ์
- นโยบายความปลอดภัยระดับแถว
- สิทธิ์ระดับคอลัมน์
- การตรวจสอบการเข้าถึง