Bảo vệ dữ liệu từng hàng với Supabase Row Level Security (RLS)
Trong thế giới phát triển ứng dụng hiện đại, việc bảo mật dữ liệu không chỉ dừng lại ở việc bảo vệ toàn bộ bảng mà còn phải kiểm soát quyền truy cập từng dòng dữ liệu cụ thể. Supabase Row Level Security (RLS) ra đời để giải quyết vấn đề này, mang đến một lớp bảo mật tinh tế và hiệu quả.
Tại sao cần Row Level Security?
Hãy tưởng tượng bạn xây dựng một ứng dụng quản lý nhân sự. Mỗi nhân viên chỉ nên xem được thông tin của chính mình, trong khi quản lý có thể xem dữ liệu của cả team. Nếu chỉ sử dụng authentication đơn thuần, bạn sẽ gặp khó khăn trong việc phân chia quyền truy cập chi tiết như vậy. Đây chính là lúc RLS phát huy sức mạnh.
Cách hoạt động của RLS trong Supabase
Supabase sử dụng PostgreSQL làm cơ sở dữ liệu, và RLS là tính năng có sẵn của PostgreSQL được Supabase tối ưu hóa. Khi RLS được bật, mọi truy vấn đều phải đi qua các policy (chính sách bảo mật) mà bạn định nghĩa.
Các thành phần chính của RLS
- Policies: Là các quy tắc xác định ai có thể truy cập dữ liệu nào - Roles: Vai trò người dùng trong hệ thống - Policies được gắn với bảng cụ thể
Thiết lập RLS cho bảng
Để bắt đầu, bạn cần bật RLS cho bảng:
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
Sau đó, tạo policy để kiểm soát truy cập:
CREATE POLICY "Users can view own profile"
ON users
FOR SELECT
USING (auth.uid() = id);
Policy này cho phép người dùng chỉ xem được dòng dữ liệu có id trùng với auth.uid() - tức là ID của người dùng đã đăng nhập.
Các loại Policy phổ biến
Policy Select (đọc dữ liệu)
CREATE POLICY "Managers can view team data"
ON employees
FOR SELECT
USING (
manager_id = auth.uid() OR
auth.jwt()->>'role' = 'admin'
);
Policy Insert (thêm dữ liệu)
CREATE POLICY "Users can add own data"
ON documents
FOR INSERT
WITH CHECK (user_id = auth.uid());
Policy Update (cập nhật dữ liệu)
CREATE POLICY "Users can update own data"
ON documents
FOR UPDATE
USING (user_id = auth.uid());
Policy Delete (xóa dữ liệu)
CREATE POLICY "Admins can delete any data"
ON documents
FOR DELETE
USING (auth.jwt()->>'role' = 'admin');
Xử lý các trường hợp phức tạp
Dữ liệu nhóm/nhóm làm việc
Với các ứng dụng có khái niệm team hoặc organization, bạn có thể lưu thông tin này trong JWT token:
CREATE POLICY "Team members can view team data"
ON projects
FOR SELECT
USING (team_id = auth.jwt()->>'team_id');
Dữ liệu công khai vs riêng tư
CREATE POLICY "Public documents are visible to everyone"
ON documents
FOR SELECT
USING (is_public = true OR user_id = auth.uid());
Best Practices khi sử dụng RLS
1. Bắt đầu với nguyên tắc "least privilege"
Chỉ cấp quyền tối thiểu cần thiết. Bắt đầu với policy hạn chế nhất, sau đó nới lỏng dần dựa trên yêu cầu thực tế.
2. Sử dụng các role một cách hiệu quả
Tận dụng hệ thống role của PostgreSQL để quản lý quyền ở mức độ cao hơn:
GRANT app_user TO read_only;
3. Kiểm thử kỹ lưỡng
Luôn kiểm thử policies với các role khác nhau để đảm bảo không có lỗ hổng bảo mật.
Quảng cáo
300x250 In-Content Advertisement
4. Sử dụng các hàm hỗ trợ
Supabase cung cấp nhiều hàm hỗ trợ trong policies:
- auth.uid(): ID của người dùng đã xác thực
- auth.jwt(): Nội dung JWT token
- is_superuser(): Kiểm tra có phải admin hay không
Lưu ý khi làm việc với RLS
1. Policies không thể tham chiếu lẫn nhau
Mỗi policy độc lập, không thể tham chiếu policy khác trong cùng bảng.
2. Không thể bypass RLS bằng cách trực tiếp query
Ngay cả khi bạn query trực tiếp lên database, RLS vẫn được áp dụng.
3. Cẩn thận với các hàm trong policies
Đảm bảo các hàm được gọi trong policies không có side effects và hoạt động hiệu quả.
Kết luận
Supabase Row Level Security là một công cụ mạnh mẽ giúp bạn bảo vệ dữ liệu một cách tinh tế và hiệu quả. Bằng cách kiểm soát quyền truy cập từng dòng dữ liệu, bạn có thể xây dựng các ứng dụng an toàn, đáp ứng các yêu cầu bảo mật phức tạp.
Điểm mạnh của RLS trong Supabase là khả năng tích hợp mượt mà với hệ thống authentication, cho phép bạn dễ dàng xây dựng các policies dựa trên thông tin người dùng. Tuy nhiên, để tận dụng tối đa tính năng này, bạn cần nắm vững các khái niệm về policies, roles, và cách chúng tương tác với nhau.
Hãy bắt đầu với các policies đơn giản, sau đó nâng cao dần theo nhu cầu ứng dụng của bạn. Nhớ rằng, bảo mật dữ liệu là một quá trình liên tục, cần được xem xét và cập nhật thường xuyên.