Row Level Security — RLS, policy yaratish
Multi-tenant ilova: har foydalanuvchi faqat o'z ma'lumotlarini ko'rishi kerak. Ilovada WHERE foydalanuvchi_id = $current_user qo'shish mumkin — lekin bir joyda unutilsa, boshqa foydalanuvchi ma'lumoti ko'rinadi.
Row Level Security (RLS) — bu tekshiruvni database darajasiga tushirish. Qaysi user bo'lishidan qat'iy nazar — faqat o'z qatorlari ko'rinadi.
RLS yoqish
-- Jadvalda RLS yoqish
ALTER TABLE buyurtmalar ENABLE ROW LEVEL SECURITY;
-- RLS yoqilgan jadvalda superuser emas foydalanuvchilar hech nima ko'rmaydi
-- Policy bo'lmasa — barcha qatorlar bloklanadi
Policy yaratish
-- Foydalanuvchi faqat o'z buyurtmalarini ko'radi
CREATE POLICY foydalanuvchi_buyurtmalari
ON buyurtmalar
FOR SELECT
USING (foydalanuvchi_id = current_user_id());
-- current_user_id() — joriy session dan foydalanuvchi ID
current_user va session variables
Joriy foydalanuvchi ID ni uzatish:
-- Session o'zgaruvchisi orqali
SET app.current_user_id = '42';
-- Policy da ishlatish
CREATE POLICY foydalanuvchi_buyurtmalari
ON buyurtmalar
FOR SELECT
USING (foydalanuvchi_id = current_setting('app.current_user_id')::INT);
Node.js da:
await client.query(`SET app.current_user_id = ${userId}`);
const { rows } = await client.query('SELECT * FROM buyurtmalar');
// Faqat shu userId ning buyurtmalari qaytadi
Turli operatsiyalar uchun policy
-- SELECT — o'z qatorlarini ko'rish
CREATE POLICY buyurtma_select ON buyurtmalar
FOR SELECT USING (foydalanuvchi_id = current_setting('app.user_id')::INT);
-- INSERT — faqat o'ziga qo'shishi mumkin
CREATE POLICY buyurtma_insert ON buyurtmalar
FOR INSERT WITH CHECK (foydalanuvchi_id = current_setting('app.user_id')::INT);
-- UPDATE — faqat o'zinkini
CREATE POLICY buyurtma_update ON buyurtmalar
FOR UPDATE USING (foydalanuvchi_id = current_setting('app.user_id')::INT);
-- DELETE — o'chirish taqiqlangan (policy yo'q = taqiq)
Admin — barcha qatorlarni ko'rish
-- Admin uchun alohida policy
CREATE POLICY admin_barcha ON buyurtmalar
FOR ALL
USING (current_setting('app.user_role') = 'admin');
Supabase va RLS
Supabase RLS ni keng ishlatadi — har jadvalda yoqiladi, auth.uid() orqali:
CREATE POLICY "Foydalanuvchi o'z profilini ko'radi"
ON profillar FOR SELECT
USING (auth.uid() = foydalanuvchi_id);
Tez-tez uchraydigan xatolar
Superuser RLS ni e'tiborga olmaydi:
-- postgres superuser RLS ni o'tkazib yuboradi
-- Test qilish uchun oddiy user bilan ulanish
RLS FORCE — superuser uchun ham:
ALTER TABLE buyurtmalar FORCE ROW LEVEL SECURITY;
-- Endi superuser ham policyga bo'ysunadi
Xulosa
ALTER TABLE jadval ENABLE ROW LEVEL SECURITY;
CREATE POLICY nom ON jadval
FOR SELECT | INSERT | UPDATE | DELETE | ALL
USING (/* mavjud qator sharti */)
WITH CHECK (/* yangi qator sharti */);
DROP POLICY nom ON jadval;
-- Session o'zgaruvchisi
SET app.user_id = '42';
current_setting('app.user_id')::INT
RLS — database darajasida qator filtrash. Ilovada WHERE unutilsa ham — database himoya qiladi.
Keyingi dars
54-dars: SQL Injection — qanday himoyalanish, parameterized query