Enregistrement du joueur
Créer un composant React pour permettre au joueur de s’enregistrer de manière sécurisée avant de commencer le quiz

Objectifs de la séance
- Comprendre ce qu’est un composant React
- Mettre en place une authentification sécurisée avec Supabase
- Utiliser un trigger pour lier un utilisateur authentifié à un joueur
- Créer des politiques RLS (Row Level Security) pour protéger les données
- Créer un formulaire d’enregistrement pour demander le pseudo du joueur
- Préparer le terrain pour enregistrer son score plus tard
Notions théoriques
Qu’est-ce qu’un composant React ?

Un composant est un bloc de code réutilisable.
Un composant peut contenir :
- du HTML (rendu à l’écran)
- du JavaScript (logique de l’interface)
- des états (
useState) pour gérer les données internes - des props (paramètres) pour personnaliser son comportement
Pourquoi créer des composants ?
- Pour organiser le code en petites parties lisibles
- Pour réutiliser des éléments (ex. : une carte, un bouton, un formulaire)
- Pour séparer les responsabilités : chaque composant a un rôle précis
Exemple simple de composant
// app/components/Bonjour.tsx
export default function Bonjour() {
return <p>Bonjour !</p>;
}
Et dans app/page.tsx :
import Bonjour from "./components/Bonjour";
export default function Home() {
return (
<div>
<Bonjour />
</div>
);
}
Composant avec état (useState)
"use client";
import { useState } from "react";
export default function Compteur() {
const [nombre, setNombre] = useState(0);
return (
<div>
<p>Vous avez cliqué {nombre} fois</p>
<button onClick={() => setNombre(nombre + 1)}>Cliquez ici</button>
</div>
);
}
Où créer les composants ?
Dans un projet Next.js, vous pouvez créer un dossier pour vos composants :
/app/components/
Chaque composant est un fichier .tsx (TypeScript + JSX).
- Le TypeScript est une extension de JavaScript qui ajoute la gestion des types.
- JSX est une syntaxe qui permet de mélanger du JavaScript et du HTML.
Étapes pour enregistrer un joueur de manière sécurisée
- Utiliser l'authentification anonyme de Supabase pour créer un utilisateur sécurisé.
- Créer un trigger qui se déclenche à la création de l'utilisateur pour l'insérer automatiquement dans la table
joueur. - Créer une politique RLS pour que chaque utilisateur ne puisse voir et modifier que ses propres données.
- Créer un composant
FormulaireJoueurqui appellesignInAnonymously. - Stocker l'ID de l'utilisateur Supabase dans le
localStorage. - Utiliser cet ID pour lier les futures actions (comme le score) au joueur.
Table joueur dans Supabase
La table joueur doit être modifiée pour être liée à la table auth.users de Supabase.
CREATE TABLE public.joueur (
id bigint GENERATED ALWAYS AS IDENTITY NOT NULL,
created_at timestamp with time zone NOT NULL DEFAULT now(),
pseudo character varying NOT NULL,
email character varying,
date_inscription date NOT NULL,
user_id uuid REFERENCES auth.users(id) ON DELETE CASCADE,
CONSTRAINT joueur_pkey PRIMARY KEY (id),
CONSTRAINT joueur_user_id_unique UNIQUE (user_id)
);
Nous utiliserons le champ pseudo pour stocker le nom du joueur et le champ user_id pour le lier de manière sécurisée à un compte Supabase.
Sécurité : Authentification et RLS
1. Activer l'authentification anonyme
Dans la console Supabase, allez dans Authentication > Settings et activez Enable anonymous sign-in.
2. Créer un trigger pour créer le joueur automatiquement
Pour garantir que chaque utilisateur authentifié a une entrée correspondante dans la table joueur, nous créons une fonction et un trigger.
-- La fonction qui sera exécutée par le trigger
CREATE OR REPLACE FUNCTION public.handle_new_user()
RETURNS TRIGGER AS $$
BEGIN
-- On récupère le pseudo depuis les métadonnées envoyées lors de l'inscription
DECLARE new_pseudo TEXT;
new_pseudo := NEW.raw_user_meta_data->>'pseudo';
-- On lève une erreur explicite si le pseudo est manquant ou vide
IF new_pseudo IS NULL OR trim(new_pseudo) = '' THEN
RAISE EXCEPTION 'Le pseudo est obligatoire pour créer un joueur.';
END IF;
-- Si le pseudo est présent, on insère la nouvelle ligne dans la table joueur
INSERT INTO public.joueur (user_id, pseudo, date_inscription)
VALUES (
NEW.id,
new_pseudo,
CURRENT_DATE
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
-- Le trigger qui déclenche la fonction après qu'un nouvel utilisateur soit créé dans auth.users
CREATE TRIGGER on_auth_user_created
AFTER INSERT ON auth.users
FOR EACH ROW EXECUTE FUNCTION public.handle_new_user();
3. Créer une politique RLS sécurisée
Activez les RLS sur la table joueur et créez une politique qui n'autorise l'accès qu'au propriétaire de la ligne.
-- Activer RLS
ALTER TABLE public.joueur ENABLE ROW LEVEL SECURITY;
-- Créer la politique sécurisée
CREATE POLICY "A user can view and modify their own player data"
ON public.joueur
FOR ALL
USING (auth.uid() = user_id)
WITH CHECK (auth.uid() = user_id);
Cette politique est beaucoup plus sûre car elle s'assure qu'un utilisateur ne peut voir ou modifier que la ligne de la table joueur qui lui est directement liée via son user_id.
Quelques méthodes à connaître
| Méthode / outil | Utilité |
|---|---|
useState | Gérer des champs de formulaire |
supabase.auth.signInAnonymously() | Créer un utilisateur anonyme sécurisé |
localStorage.setItem(...) | Mémoriser un ID dans le navigateur |
onSubmit={handleSubmit} | Gérer l’envoi d’un formulaire |
preventDefault() | Empêcher le rechargement de la page |
Test de mémorisation / compréhension
TP pour réfléchir et résoudre des problèmes
Objectif
Créer un formulaire de début de partie et enregistrer le joueur de manière sécurisée en le liant au système d'authentification de Supabase.

Lorsque le joueur a saisi son nom et clique sur le bouton Commencer le quiz :
- authentifier l'utilisateur anonymement
- insérer un joueur dans Supabase (via un trigger)
- stocker l’ID de l'utilisateur Supabase dans
localStorage
Étapes du TP
- Modifier la table
joueur - Créer un trigger
- Créer une RLS
- Ajouter les valeurs par défaut
- Créer un composant
FormulaireJoueur.tsxpour afficher un formulaire avec un champPseudoobligatoire - Modifier app/page.tsx pour afficher ce formulaire avant le quiz pour afficher ce composant dans
app/page.tsxavant le quiz et n'autoriser l’accès au quiz que si un joueur est enregistré
Étape 1 : Modifier la table joueur
Utiliser l'authentification de Supabase pour lier chaque joueur à un utilisateur sécurisé
Supabase offre une authentification anonyme qui crée un utilisateur temporaire dans la table auth.users.
Cette authentification fournie par Supabase vous donne un auth.uid() fiable et sécurisé à utiliser dans vos politiques RLS.
Nous allons lier chaque joueur à un utilisateur de la table auth.users.
📌 Qu'est-ce que la table auth.users ?
La table auth.users est une table spéciale gérée par Supabase qui stocke les informations des utilisateurs authentifiés. Elle contient des champs comme id, email, created_at, etc. Le champ id est un identifiant unique pour chaque utilisateur, souvent de type uuid.

Pour gérer les utilisateurs, dans Supabase, il suffit d'aller dans l'onglet Authentication > Users.
La meilleure façon de lier les joueurs à la table auth.users, c'est :
-
d'ajouter une colonne
user_idde typeuuidet d'y mettre une clé étrangère-- Ajouter une colonne pour lier chaque joueur à un utilisateur SupabaseALTER TABLE public.joueurADD COLUMN user_id uuid REFERENCES auth.users(id) ON DELETE CASCADE;
-
de la rendre colonne
user_idunique pour garantir une relation 1-pour-1-- Rendre cette colonne unique pour garantir la relation 1-pour-1ALTER TABLE public.joueur ADD CONSTRAINT joueur_user_id_unique UNIQUE (user_id);
Étape 2 : Créer un trigger
Créer un trigger pour créer le joueur automatiquement
Pour que le processus soit fluide et sécurisé, on va créer un trigger qui, dès qu'un utilisateur s'inscrit (anonymement), crée automatiquement une ligne correspondante dans la table joueur.
Nous apprendrons plus tard à créer des triggers
Voici le code SQL pour créer la fonction qui sera exécutée par le trigger :
-- Fonction qui sera exécutée par le trigger
-- On utilise CREATE OR REPLACE pour mettre à jour la fonction existante
CREATE OR REPLACE FUNCTION public.handle_new_user()
RETURNS TRIGGER AS $$ DECLARE
-- La déclaration des variables doit se faire AVANT le bloc BEGIN
new_pseudo TEXT;
BEGIN
-- On récupère le pseudo depuis les métadonnées envoyées lors de l'inscription
new_pseudo := NEW.raw_user_meta_data->>'pseudo';
-- On lève une erreur explicite si le pseudo est manquant ou vide
IF new_pseudo IS NULL OR trim(new_pseudo) = '' THEN
RAISE EXCEPTION 'Le pseudo est obligatoire pour créer un joueur.';
END IF;
-- Si le pseudo est présent, on insère la nouvelle ligne dans la table joueur
INSERT INTO public.joueur (user_id, pseudo, date_inscription)
VALUES (
NEW.id,
new_pseudo,
CURRENT_DATE
);
RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

Voici le code SQL pour créer le trigger qui utilise cette fonction :
-- Trigger qui déclenche la fonction après qu'un nouvel utilisateur soit créé dans auth.users
CREATE TRIGGER on_auth_user_created
AFTER INSERT ON auth.users
FOR EACH ROW EXECUTE FUNCTION public.handle_new_user();
