Row Level Security (RLS) trong PostgreSQL là gì? Nó khác gì với GRANT?
Gợi ý trả lời
PostgreSQL có hai lớp kiểm soát quyền trên một bảng, và câu trả lời tốt phân biệt được chúng.
GRANT quyết định một vai được làm thao tác gì trên bảng: select, insert, update, delete. Nó không phân biệt các dòng, đã cho select là đọc được mọi dòng.
Row Level Security quyết định vai đó được đụng tới những dòng nào. Sau khi chạy alter table ... enable row level security, mỗi thao tác phải thỏa một policy, tức một điều kiện SQL kiểm tra trên từng dòng. Ví dụ cho blog:
create policy "Ai cũng đọc được bài đã đăng" on posts for select
to anon using (status = 'published' and published_at <= now());Vài ý nên nêu để cho thấy bạn đã dùng thật:
- Bật RLS mà không có policy thì mặc định từ chối tất cả. Câu
selectkhông báo lỗi mà trả về 0 dòng, nên trang trống dù bảng có dữ liệu. Đây là lỗi rất hay gặp. - Thao tác ghi bị chặn im lặng:
updatevàdeletetrên dòng không được thấy sẽ ảnh hưởng 0 dòng, còninsertvi phạm policy thì báo lỗi. - Chủ bảng, superuser và vai có BYPASSRLS bỏ qua RLS. Vì vậy thử policy phải dùng đúng vai của ứng dụng (ví dụ
set role anon), và khóa quản trị không bao giờ được nằm ở trình duyệt. - Vì sao cần RLS khi đã lọc trong code: với các nền tảng cho trình duyệt gọi thẳng database qua API (như Supabase), khóa nằm ở phía client nên ai cũng gọi được. Bộ lọc trong code không bảo vệ được gì, policy trong database mới là thứ chặn.
Điểm cộng: nói rằng nên dùng cả hai lớp, chỉ grant đúng thao tác cần thiết, để một lần cấp nhầm quyền không làm lộ hay mất dữ liệu.