BaliseTonSite

Row Level Security

La sécurité au niveau de chaque ligne : chaque utilisateur ne voit que ses propres données.

5.1Pourquoi RLS est indispensable

Ta anon key est publique (visible dans le code client). Sans RLS, voici ce qui se passe :

Sans RLS

  • - N'importe qui peut lire toutes les données
  • - N'importe qui peut modifier les données des autres
  • - N'importe qui peut supprimer ce qu'il veut
  • - Ta base est un buffet à volonté

Avec RLS

  • - Chaque utilisateur ne voit que ses données
  • - Impossible de modifier les données d'un autre
  • - Les policies sont évaluées à chaque requête
  • - La sécurité est dans la base, pas dans ton code

5.2Activer RLS

Activer RLS sur une tablebash
-- TOUJOURS activer RLS sur les tables publiques
ALTER TABLE public.articles ENABLE ROW LEVEL SECURITY;

-- Par défaut, une fois RLS activé, PERSONNE n'a accès
-- (même pas l'utilisateur connecté)
-- Il faut créer des policies pour autoriser les opérations

5.3Créer des policies

Une policy RLS est une règle SQL qui dit : "qui peut faire quoi sur quelles lignes".

Policy : chacun lit ses propres articlesbash
CREATE POLICY "Users can read own articles"
  ON public.articles
  FOR SELECT
  USING (auth.uid() = author_id);

-- auth.uid() = l'ID de l'utilisateur connecté (extrait du JWT)
-- Cette policy dit : "tu ne peux SELECT que les lignes
-- où author_id correspond à ton ID"
Policy : chacun insère pour lui-mêmebash
CREATE POLICY "Users can insert own articles"
  ON public.articles
  FOR INSERT
  WITH CHECK (auth.uid() = author_id);

-- WITH CHECK valide les données AVANT l'insertion
-- Empêche un utilisateur d'insérer avec l'ID d'un autre
Policy : chacun modifie/supprime les siensbash
CREATE POLICY "Users can update own articles"
  ON public.articles
  FOR UPDATE
  USING (auth.uid() = author_id)
  WITH CHECK (auth.uid() = author_id);

CREATE POLICY "Users can delete own articles"
  ON public.articles
  FOR DELETE
  USING (auth.uid() = author_id);

5.4Patterns courants de policies

Pattern 1 : Tout le monde peut lire, seul l'auteur modifiebash
-- Articles publiés : lecture publique
CREATE POLICY "Public can read published articles"
  ON public.articles
  FOR SELECT
  USING (published = true);

-- Auteur : CRUD complet sur ses propres articles
CREATE POLICY "Authors can manage own articles"
  ON public.articles
  FOR ALL
  USING (auth.uid() = author_id)
  WITH CHECK (auth.uid() = author_id);
Pattern 2 : Lecture pour les utilisateurs connectésbash
-- Toute personne connectée peut lire
CREATE POLICY "Authenticated users can read"
  ON public.articles
  FOR SELECT
  TO authenticated  -- Rôle Supabase : 'authenticated' = connecté
  USING (true);
Pattern 3 : Insertion côté serveur uniquementbash
-- Les visiteurs ne doivent jamais écrire directement dans cette table
ALTER TABLE public.contact_messages ENABLE ROW LEVEL SECURITY;

-- Aucune policy INSERT pour 'anon' ou 'authenticated'.
-- Une route serveur valide les données puis utilise la clé service_role.
-- Cette clé reste secrète et n'est jamais envoyée au navigateur.

5.5USING vs WITH CHECK

ClauseQuandUsage
USINGSELECT, UPDATE, DELETEFiltre les lignes existantes auxquelles tu as accès
WITH CHECKINSERT, UPDATEValide les nouvelles données avant écriture

5.6Exemple complet : une plateforme d'apprentissage

Trois tables personnelles protégées par RLSbash
-- Table progression
CREATE TABLE public.chapter_progress (
  user_id UUID REFERENCES auth.users(id) NOT NULL,
  course_id TEXT NOT NULL,
  chapter_slug TEXT NOT NULL,
  completed_at TIMESTAMPTZ,
  PRIMARY KEY (user_id, course_id, chapter_slug)
);
ALTER TABLE public.chapter_progress ENABLE ROW LEVEL SECURITY;
CREATE POLICY "rw_own_progress" ON public.chapter_progress FOR ALL
  USING (auth.uid() = user_id)
  WITH CHECK (auth.uid() = user_id);

-- Table résultats des QCM
CREATE TABLE public.chapter_quiz_results (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  user_id UUID REFERENCES auth.users(id) NOT NULL,
  course_id TEXT NOT NULL,
  chapter_slug TEXT NOT NULL,
  score INTEGER NOT NULL,
  total_questions INTEGER NOT NULL,
  UNIQUE(user_id, course_id, chapter_slug)
);
ALTER TABLE public.chapter_quiz_results ENABLE ROW LEVEL SECURITY;
CREATE POLICY "rw_own_quiz" ON public.chapter_quiz_results FOR ALL
  USING (auth.uid() = user_id)
  WITH CHECK (auth.uid() = user_id);

-- Table auto-évaluation
CREATE TABLE public.chapter_feedback (
  id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  user_id UUID REFERENCES auth.users(id) NOT NULL,
  course_id TEXT NOT NULL,
  chapter_slug TEXT NOT NULL,
  rating TEXT NOT NULL,
  UNIQUE(user_id, course_id, chapter_slug)
);
ALTER TABLE public.chapter_feedback ENABLE ROW LEVEL SECURITY;
CREATE POLICY "rw_own_feedback" ON public.chapter_feedback FOR ALL
  USING (auth.uid() = user_id)
  WITH CHECK (auth.uid() = user_id);

Verifie tes acquis

5 questions pour valider ce chapitre

1. Que se passe-t-il si RLS est active sur une table SANS aucune policy ?

Valide et sauvegarde ce chapitre

Ne perds pas le fil de ton apprentissage. Chaque QCM terminé sauvegarde ton score. Crée ton profil gratuitement pour débloquer toutes les évaluations du site et retrouver tes résultats plus tard.

Commencer l'aventure
Déjà membre ?Connecte-toi