D-OPEN

Comment configurer l'authentification OAuth2 avec Supabase dans Next.js 15 en 8 etapes

Lucas Moreau

Lucas Moreau

Developpeur full-stack Next.js · 18 avril 2026 · 15 min de lecture

TL;DR

  • Implementer OAuth2 avec Supabase Auth et Next.js 15 App Router prend environ 3 heures pour un developpeur senior, 8 a 12 heures pour un junior.
  • Utilisez @supabase/ssr (pas @supabase/auth-helpers qui est en legacy) pour gerer proprement les cookies cote Server Components.
  • Activez le Row Level Security sur toutes vos tables Postgres avant de mettre en ligne.
  • Code complet, pieges frequents et verification production inclus dans ce guide.

L'authentification OAuth2 est le premier chantier serieux d'une application SaaS Next.js 15. En 2026, la combinaison Supabase Auth + Next.js 15 App Router + @supabase/ssr est devenue le standard pour les PME et startups francaises qui veulent un systeme complet sans payer Auth0. Voici la methode testee en production, en 8 etapes operationnelles avec le code complet.

Etape 1 : creer le projet Supabase et recuperer les cles

Ouvrez supabase.com, creez un nouveau projet. Choisissez la region eu-west-3 (Paris) pour minimiser la latence et respecter le RGPD si vos utilisateurs sont francais. Une fois le projet provisionne (environ 2 minutes), allez dans Project Settings > API et notez trois valeurs : URL, anon public key et service_role key. La derniere ne doit jamais atterrir cote client.

Etape 2 : installer les packages

npm install @supabase/supabase-js @supabase/ssr npm install --save-dev @types/node

Confirmez que vous etes sur Next.js 15.2+ (npx next --version). Si vous etes encore en 14, mettez a jour avant d'aller plus loin - plusieurs API Server Actions ont change.

Etape 3 : configurer les clients Supabase

Creez trois fichiers. D'abord lib/supabase/client.ts pour le cote navigateur :

import { createBrowserClient } from '@supabase/ssr';

export function createClient() {
  return createBrowserClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
  );
}

Puis lib/supabase/server.ts pour les Server Components :

import { createServerClient } from '@supabase/ssr';
import { cookies } from 'next/headers';

export async function createClient() {
  const cookieStore = await cookies();
  return createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() { return cookieStore.getAll(); },
        setAll(cookiesToSet) {
          try {
            cookiesToSet.forEach(({ name, value, options }) =>
              cookieStore.set(name, value, options));
          } catch {}
        },
      },
    }
  );
}

Etape 4 : declarer les providers Google et GitHub

Dans Supabase, Authentication > Providers. Activez Google et GitHub. Pour Google, creez un projet sur console.cloud.google.com et generez un OAuth Client ID. L'URL de redirection a copier dans Google est celle indiquee par Supabase : https://<project-ref>.supabase.co/auth/v1/callback. Idem pour GitHub via Settings > Developer settings > OAuth Apps.

Etape 5 : implementer la route callback OAuth2

Creez app/auth/callback/route.ts. Cette route recoit le code echange par Supabase et cree la session cookie :

import { NextResponse } from 'next/server';
import { createClient } from '@/lib/supabase/server';

export async function GET(request: Request) {
  const { searchParams, origin } = new URL(request.url);
  const code = searchParams.get('code');
  const next = searchParams.get('next') ?? '/dashboard';

  if (code) {
    const supabase = await createClient();
    const { error } = await supabase.auth.exchangeCodeForSession(code);
    if (!error) return NextResponse.redirect(`${origin}${next}`);
  }
  return NextResponse.redirect(`${origin}/auth/auth-code-error`);
}

Pensez a gerer explicitement le cas d'erreur pour ne pas laisser l'utilisateur sur une page blanche.

Etape 6 : proteger les routes avec un middleware

Creez middleware.ts a la racine du projet. Il rafraichit automatiquement la session et protege les routes derriere un pattern :

import { NextResponse, type NextRequest } from 'next/server';
import { createServerClient } from '@supabase/ssr';

export async function middleware(request: NextRequest) {
  let response = NextResponse.next();
  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() { return request.cookies.getAll(); },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value, options }) =>
            response.cookies.set(name, value, options));
        },
      },
    }
  );
  const { data: { user } } = await supabase.auth.getUser();
  if (!user && request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', request.url));
  }
  return response;
}

export const config = { matcher: ['/dashboard/:path*', '/account/:path*'] };
“Le piege numero un que je vois dans les audits : les equipes utilisent supabase.auth.getSession() cote serveur alors qu'il faut getUser(). getSession() fait confiance au cookie qui peut etre fabrique cote client, getUser() valide le JWT contre le serveur Supabase.” — Lucas Moreau, D-Open

Etape 7 : activer le Row Level Security

Dans l'editeur SQL Supabase, executez pour chaque table :

ALTER TABLE public.projects ENABLE ROW LEVEL SECURITY;

CREATE POLICY "own rows only" ON public.projects
  FOR ALL
  USING (auth.uid() = user_id)
  WITH CHECK (auth.uid() = user_id);

Testez systematiquement avec deux comptes utilisateurs differents. Si l'utilisateur A voit une ligne de l'utilisateur B, votre policy est mal ecrite. Pour automatiser les tests, inspirez-vous de notre guide securiser une application web open source avec l OWASP Top 10.

Etape 8 : deployer sur Vercel

Dans Vercel, ajoutez les variables d'environnement NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY, et SUPABASE_SERVICE_ROLE_KEY (pour les Server Actions admin). Dans Supabase, Authentication > URL Configuration, ajoutez l'URL de production comme Site URL et toutes les URLs de preview comme Additional Redirect URLs. Sans ca, le callback echoue sur les previews.

💡 Recommandation production

Activez la MFA obligatoire pour les comptes admin (Authentication > MFA) et configurez les webhooks Auth Hooks pour envoyer les events signup et login vers votre outil d'observabilite. Sans ca, vous decouvrirez les attaques de credential stuffing trop tard.

Pieges frequents en production

  1. Erreur PKCE sur mobile : assurez-vous que flowType: 'pkce' est actif cote client si vous ciblez iOS / Android.
  2. Session perdue sur Vercel Preview : les URLs de preview doivent etre dans la whitelist Supabase.
  3. RLS trop restrictive : les Server Actions admin doivent utiliser la service_role key, pas la session utilisateur.
  4. Tokens expirés : @supabase/ssr refresh automatiquement, mais uniquement si le middleware s'execute sur la route.

FAQ

Supabase Auth est-il production-ready en 2026 ?

Oui. Utilise par des milliers de PME et startups depuis 2022. Solide sur Next.js 15 avec @supabase/ssr. Seules limites : pas de SAML natif sur le plan gratuit, MFA basique comparee a Auth0.

Faut-il utiliser @supabase/auth-helpers ou @supabase/ssr ?

Utilisez @supabase/ssr. @supabase/auth-helpers est en legacy depuis fin 2024.

Pourquoi activer le Row Level Security ?

Sans RLS, toutes les donnees sont accessibles a n'importe quel utilisateur authentifie. RLS est la couche fondamentale de securite Supabase.

Comment gerer les variables d'environnement sur Vercel ?

NEXT_PUBLIC_SUPABASE_URL et NEXT_PUBLIC_SUPABASE_ANON_KEY exposees au client, SUPABASE_SERVICE_ROLE_KEY seulement cote serveur. Si service_role est exposee, regenerez-la immediatement.

Besoin d'aide pour securiser votre app Next.js ?

D-Open implemente l'authentification OAuth2, MFA et RLS en production pour les startups francaises. Pair programming inclus.

Discuter du projet →

Lancer votre SaaS Next.js en 2026 ?

D-Open livre des MVP Next.js 15 + Supabase + Stripe en 4 a 6 semaines. Architecture, code, deploiement, formation.

Demander un devis →