Les JWT (JSON Web Tokens) sont au cœur du système d’authentification Supabase. Comprendre leur fonctionnement vous permet de sécuriser votre application, créer des policies avancées, et intégrer Supabase avec des services tiers.
Pour le contexte global, consultez notre guide complet Supabase. Pour l’authentification en pratique, voir Supabase Auth. Pour exploiter les JWT dans vos policies RLS, voir Supabase RLS. Pour les custom claims via triggers, voir SQL, triggers et fonctions Supabase. Pour la gestion des rôles basée sur JWT, voir Supabase Rôles et Permissions.
Qu’est-ce qu’un JWT ?
Un JWT est un token signé contenant des informations (claims) sur l’utilisateur. Il se compose de 3 parties séparées par des points :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 // Header (encodé Base64)
.eyJzdWIiOiJ1c2VyLXV1aWQiLCJyb2xlIjoiYXV0aGVudGljYXRlZCJ9 // Payload
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c // Signature
Structure du JWT Supabase
{
"iss": "https://[project-ref].supabase.co/auth/v1",
"sub": "user-uuid-here",
"aud": "authenticated",
"exp": 1700000000,
"iat": 1699996400,
"role": "authenticated",
"email": "user@example.com",
"app_metadata": {
"provider": "email",
"providers": ["email", "google"]
},
"user_metadata": {
"first_name": "Jean",
"username": "jeandupont"
},
"session_id": "session-uuid"
}
Les Deux Clés JWT Supabase
| Clé | Rôle JWT | Usage | Sécurité |
|---|---|---|---|
| anon key | anon | Frontend, API publique | Peut être exposée (RLS protège) |
| service_role key | service_role | Backend serveur uniquement | ⚠️ JAMAIS côté client |
Accéder au JWT dans PostgreSQL
-- Accéder aux claims du JWT
SELECT auth.jwt();
SELECT auth.jwt()->>'sub'; -- User UUID
SELECT auth.jwt()->>'role'; -- 'authenticated' ou 'anon'
SELECT auth.jwt()->>'email'; -- Email de l'utilisateur
SELECT auth.jwt()->'user_metadata'->>'username'; -- Métadonnée
-- auth.uid() est équivalent à auth.jwt()->>'sub'
SELECT auth.uid();
Durée de Vie et Refresh des Tokens
const { data, error } = await supabase.auth.refreshSession()
const { data: { session } } = await supabase.auth.getSession()
console.log('Access token:', session?.access_token)
console.log('Expire à:', new Date(session?.expires_at! * 1000))
JWT Claims Personnalisés (Custom Claims)
CREATE OR REPLACE FUNCTION public.custom_access_token_hook(event JSONB)
RETURNS JSONB AS $$
DECLARE
claims JSONB;
subscription_tier TEXT;
org_id UUID;
BEGIN
SELECT p.subscription_tier, p.organization_id
INTO subscription_tier, org_id
FROM profiles p
WHERE p.id = (event->>'user_id')::UUID;
claims := event->'claims';
claims := jsonb_set(claims, '{subscription}', to_jsonb(subscription_tier));
claims := jsonb_set(claims, '{org_id}', to_jsonb(org_id::TEXT));
RETURN jsonb_set(event, '{claims}', claims);
END;
$$ LANGUAGE plpgsql STABLE SECURITY DEFINER;
Valider un JWT côté Serveur
export async function GET(request: Request) {
const authHeader = request.headers.get('Authorization')
if (!authHeader?.startsWith('Bearer ')) {
return Response.json({ error: 'Non autorisé' }, { status: 401 })
}
const token = authHeader.split(' ')[1]
const supabase = createClient(
process.env.SUPABASE_URL!,
process.env.SUPABASE_ANON_KEY!,
{
global: { headers: { Authorization: `Bearer ${token}` } }
}
)
const { data: { user }, error } = await supabase.auth.getUser()
if (error || !user) {
return Response.json({ error: 'Token invalide' }, { status: 401 })
}
return Response.json({ user })
}
⚠️ Ne jamais faire confiance aux claims décodés côté client sans vérification serveur. Pour la validation côté serveur, utilisez toujours supabase.auth.getUser(token).
👉 Articles du guide Supabase
Cet article fait partie du Guide Complet Supabase 2026. Retrouvez les autres articles :
- ✅ Supabase : Le Guide Complet 2026
- ✅ Supabase vs Firebase : Comparatif Complet 2026
- ✅ Installer Supabase en Local avec Docker
- ✅ Supabase Pricing : Quel Plan Choisir en 2026
- ✅ Architecture Supabase : Postgres, GoTrue, Realtime et Storage
- ✅ Créer et Structurer sa Base de Données Supabase
- ✅ Supabase RLS : Sécuriser ses Données avec Row Level Security
- ✅ Supabase SQL : Triggers, Fonctions et Procédures Stockées
- ✅ Supabase Migrations : Gérer l’Évolution de son Schéma
- ✅ Supabase Auth : Email, OAuth et Magic Links
- ✅ Supabase Rôles et Permissions
- 📅 Supabase + Next.js — à paraître le 20/06
- 📅 Supabase + React — à paraître le 22/06
- 📅 API REST Supabase — à paraître le 24/06
- 📅 Edge Functions — à paraître le 26/06
- 📅 Realtime Supabase — à paraître le 28/06
- 📅 Storage Supabase — à paraître le 30/06
- 📅 Vector & pgvector — à paraître le 02/07
- 📅 Supabase MCP — à paraître le 04/07
- 📅 Déploiement en production — à paraître le 06/07
- 📅 CLI Supabase — à paraître le 08/07





