Bảo vệ dữ liệu từng hàng với Row Level Security trong Supabase
Khi ứng dụng của bạn phát triển và lượng dữ liệu tăng lên, việc đảm bảo mỗi người dùng chỉ nhìn thấy những thông tin họ được phép truy cập trở thành ưu tiên hàng đầu. Supabase, với nền tảng PostgreSQL mạnh mẽ, cung cấp một tính năng gọi là Row Level Security (RLS) giúp bạn kiểm soát truy cập dữ liệu ngay tại cơ sở dữ liệu. Bài viết này sẽ hướng dẫn bạn cách sử dụng RLS để bảo vệ dữ liệu một cách hiệu quả và an toàn.
Row Level Security là gì?
Row Level Security là một tính năng của PostgreSQL cho phép bạn định nghĩa các quy tắc (policy) để kiểm soát ai có thể đọc, chèn, cập nhật hoặc xóa từng hàng trong bảng. Thay vì dựa vào ứng dụng để lọc dữ liệu, RLS đảm bảo rằng chỉ những hàng hợp lệ mới được truy cập, ngay cả khi ai đó cố tình bỏ qua lớp bảo mật ở ứng dụng.
Bật RLS cho bảng
Trước khi tạo policy, bạn cần bật RLS cho bảng:
ALTER TABLE your_table ENABLE ROW LEVEL SECURITY;
Khi RLS được bật, mọi truy vấn vào bảng sẽ bị chặn trừ khi có policy cho phép. Điều này đảm bảo không có hàng nào bị lộ ngoài ý muốn.
Tạo policy cho từng hành động
1. Policy cho phép người dùng xem dữ liệu của chính họ
Giả sử bạn có bảng profiles với cột user_id tham chiếu đến auth.users. Bạn muốn mỗi người dùng chỉ thấy profile của mình:
CREATE POLICY "Users can view own profiles" ON profiles
FOR SELECT USING (auth.uid() = user_id);
2. Policy cho phép người dùng cập nhật dữ liệu của chính họ
CREATE POLICY "Users can update own profiles" ON profiles
FOR UPDATE USING (auth.uid() = user_id);
3. Policy cho phép người dùng chèn dữ liệu mới
CREATE POLICY "Users can insert own profiles" ON profiles
FOR INSERT WITH CHECK (auth.uid() = user_id);
4. Policy cho phép người dùng xóa dữ liệu của chính họ
CREATE POLICY "Users can delete own profiles" ON profiles
FOR DELETE USING (auth.uid() = user_id);
Sử dụng policy cho nhiều người dùng
Nếu bạn cần cho phép admin xem tất cả hồ sơ, bạn có thể kết hợp policy:
CREATE POLICY "Admins can view all profiles" ON profiles
FOR SELECT USING (auth.jwt() ->> 'role' = 'admin');
Hoặc tạo policy riêng cho admin:
Quảng cáo
300x250 In-Content Advertisement
CREATE POLICY "Admins full access" ON profiles
FOR ALL USING (auth.jwt() ->> 'role' = 'admin');
Kiểm tra và debug policy
Để xem danh sách policy hiện tại:
SELECT * FROM pg_policies WHERE tablename = 'your_table';
Để kiểm tra policy có hoạt động không, bạn có thể thử truy vấn với user cụ thể:
SET ROLE 'authenticated';
SELECT * FROM profiles;
Nếu policy được định nghĩa đúng, bạn chỉ thấy những hàng được cho phép.
Lưu ý khi sử dụng RLS
- Luôn bật RLS: Khi RLS được bật, mọi truy vấn sẽ bị chặn nếu không có policy. Đảm bảo bạn tạo policy trước khi bật RLS. - Kiểm tra quyền: RLS không thay thế quyền cơ sở dữ liệu. Người dùng vẫn cần quyền SELECT, INSERT, UPDATE, DELETE trên bảng. - Test kỹ lưỡng: Luôn test policy với các role khác nhau để đảm bảo chỉ những dữ liệu được cho phép mới hiển thị. - Sử dụng auth.uid() và auth.jwt(): Hai hàm này giúp bạn truy cập thông tin user đã đăng nhập.
Kết luận
Row Level Security trong Supabase giúp bạn bảo vệ dữ liệu một cách mạnh mẽ và linh hoạt. Bằng cách định nghĩa policy rõ ràng, bạn đảm bảo mỗi người dùng chỉ thấy những gì họ được phép, giảm thiểu rủi ro rò rỉ thông tin. Hãy bắt đầu với các policy đơn giản, test kỹ lưỡng và mở rộng dần khi ứng dụng của bạn phát triển. Với RLS, dữ liệu của bạn sẽ được bảo vệ ngay từ tầng cơ sở dữ liệu, mang lại sự an tâm cho cả nhà phát triển và người dùng.