Spis treściKliknij link, aby przejść do wybranego miejsca
Ta treść została automatycznie przetłumaczona z ukraińskiego.
W PostgreSQL jest potężna, ale często niedoceniana funkcja - Row Level Security (RLS). Mówiąc krótko, to ochrona danych na poziomie wierszy tabeli, czyli - system decyduje, które dokładnie rekordy użytkownik może zobaczyć lub zmienić, jeszcze zanim zapytanie trafi do twojego kodu Rails.
Jak to działa
W normalnej sytuacji dostęp do danych kontrolowany jest w aplikacji - na przykład w Rails piszemy:
@posts = Post.where(user_id: current_user.id)
Jednak RLS pozwala delegować tę kontrolę samej bazie. Włączasz politykę bezpieczeństwa dla tabeli:
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
CREATE POLICY user_is_owner
ON posts
FOR SELECT USING (user_id = current_setting('app.current_user_id')::int);
Po tym nawet jeśli ktoś wykona SELECT * FROM posts, PostgreSQL automatycznie wstawi warunek, aby użytkownik widział tylko swoje wiersze.
Jak zintegrować RLS w Rails
W Rails można przed wykonaniem zapytania ustawić current_user.id w kontekście bazy:
ActiveRecord::Base.connection.execute("SET app.current_user_id = #{current_user.id}")
I wtedy wszystkie zapytania (Post.all, Post.find, nawet joins) będą zwracać tylko dozwolone dane - bez dodatkowych where w kodzie.
To jest wygodne dla systemów wielodostępnych, SaaS lub API, gdzie bezpieczeństwo nie powinno zależeć tylko od poziomu aplikacji.
Po co to w ogóle
- Bezpieczeństwo na poziomie Bazy Danych - nawet jeśli ktoś omyłkowo zapomni o where(user_id: ...), dane nie wyciekną.
- Prostota zapytań - można pisać Model.all, nie myśląc o filtrach.
- Jednolity kontrola dostępu - zasady są przechowywane razem z danymi, a nie rozrzucone po kontrolerach i serwisach.
RLS nie zastępuje autoryzacji w aplikacji. Jest to dodatkowy poziom ochrony, który gwarantuje, że nawet na niskim poziomie nikt nie uzyska "zbędnych" danych. Row Level Security - to jak where(user_id: current_user.id), ale wbudowane w samą bazę danych.
Ten post nie ma jeszcze żadnych dodatków od autora.