Passer au contenu principal

Utiliser l’IA pour intégrer Auth0

Si vous utilisez un assistant de programmation par IA comme Claude Code, Cursor ou GitHub Copilot, vous pouvez ajouter automatiquement l’authentification avec Auth0 en quelques minutes à l’aide des agent skills.Installer :
npx skills add auth0/agent-skills --skill auth0-quickstart --skill auth0-nextjs
Demandez ensuite à votre assistant IA :
Add Auth0 authentication to my Next.js app
Votre assistant IA créera automatiquement votre application Auth0, récupérera les identifiants, installera @auth0/nextjs-auth0, créera les routes API et configurera les variables d’environnement. Documentation complète des agent skills →
Prérequis : Avant de commencer, assurez-vous d’avoir installé les éléments suivants :Vérifiez l’installation : node --version && npm --version

Pour commencer

Ce guide de démarrage rapide explique comment ajouter l’authentification Auth0 à une application Next.js 16. Vous créerez une application Web complète avec rendu côté serveur, un mécanisme de connexion sécurisé et des routes protégées à l’aide du SDK Next.js d’Auth0.
1

Créer un nouveau projet

Créez un nouveau projet Next.js pour ce guide de démarrage rapide
npx create-next-app@latest auth0-nextjs --typescript --tailwind --eslint --app --src-dir --import-alias "@/*" --yes
Ouvrez le projet
cd auth0-nextjs
2

Installer le SDK Auth0 pour Next.js

shellscript npm install @auth0/nextjs-auth0
3

Créer les fichiers du projet

Créez tous les répertoires et fichiers nécessaires à l’intégration d’Auth0 :
mkdir -p src/lib src/components && touch src/lib/auth0.ts src/proxy.ts src/components/LoginButton.tsx src/components/LogoutButton.tsx src/components/Profile.tsx
4

Configurez votre application Auth0

Ensuite, créez une nouvelle application sur votre locataire Auth0 et ajoutez les variables d’environnement à votre projet.Vous disposez de trois options pour configurer votre application Auth0 : utiliser l’outil Quick Setup (recommandé), exécuter une commande CLI ou effectuer la configuration manuellement via le Auth0 Dashboard :
Créez une application Auth0 et copiez le fichier .env prérempli avec les bonnes valeurs de configuration.
5

Créer la configuration d’Auth0

Ajoutez le code du client Auth0 dans src/lib/auth0.ts :
src/lib/auth0.ts
import { Auth0Client } from '@auth0/nextjs-auth0/server';

export const auth0 = new Auth0Client();
6

Ajouter un proxy

Ajoutez le code du proxy dans src/proxy.ts :
src/proxy.ts
import { auth0 } from "./lib/auth0";

export async function proxy(request: Request) {
  return await auth0.middleware(request);
}

export const config = {
  matcher: [
    /*
     * Correspond à tous les chemins de requête sauf ceux commençant par :
     * - _next/static (fichiers statiques)
     * - _next/image (fichiers d'optimisation d'images)
     * - favicon.ico, sitemap.xml, robots.txt (fichiers de métadonnées)
     */
    "/((?!_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)",
  ],
};
Comme nous utilisons un répertoire src/, le fichier proxy.ts est créé dans src/. Si vous n’utilisez pas de répertoire src/, créez-le plutôt à la racine du projet.
Ce proxy configure automatiquement les routes d’authentification suivantes :
  • /auth/login - Route de connexion
  • /auth/logout - Route de déconnexion
  • /auth/callback - Route de rappel
  • /auth/profile - Route du profil utilisateur
  • /auth/access-token - Route du jeton d’accès
  • /auth/backchannel-logout - Route de déconnexion par canal arrière
7

Créer les composants Login, Logout et Profile

Ajoutez le code des composants dans les fichiers créés à l’étape 3 :
8

Mettez à jour votre page d’accueil

Remplacez src/app/page.tsx par :
src/app/page.tsx
import { auth0 } from "@/lib/auth0";
import LoginButton from "@/components/LoginButton";
import LogoutButton from "@/components/LogoutButton";
import Profile from "@/components/Profile";

export default async function Home() {
  const session = await auth0.getSession();
  const user = session?.user;

  return (
    <main className="min-h-screen bg-[#efefef] flex flex-col items-center justify-center gap-4 px-6 py-12">
      <div className="bg-white rounded-[28px] shadow-[0_4px_32px_rgba(0,0,0,0.08)] px-12 py-14 flex flex-col items-center gap-4 w-[360px]">
        <svg width="68" height="68" viewBox="0 0 68 68" fill="none" xmlns="http://www.w3.org/2000/svg" className="mb-1">
          <g filter="url(#filter0_di)">
            <rect x="2" y="2" width="64" height="64" rx="16" fill="url(#paint0_linear)"/>
            <rect x="2.5" y="2.5" width="63" height="63" rx="15.5" stroke="#252525"/>
            <path d="M34.0002 18C25.1572 18 18 25.1669 18 34C18 42.8432 25.1672 50 34.0002 50C42.8333 50 50 42.8331 50 34C50 25.1669 42.8433 18 34.0002 18ZM43.9172 43.8971C43.9172 43.9071 43.9069 43.9072 43.9069 43.9172C43.9069 43.9172 43.8969 43.9272 43.8868 43.9272C43.144 44.65 41.9796 44.7303 41.0662 44.2585L40.0228 43.7265C36.2487 41.7792 31.7619 41.7792 27.9777 43.7265L26.9338 44.2585C26.0103 44.7303 24.8459 44.65 24.1132 43.9272C24.1132 43.9272 24.1031 43.9172 24.0931 43.9172C24.0931 43.9172 24.0828 43.9071 24.0828 43.8971C23.3601 43.1543 23.2797 41.9899 23.7515 41.0765L24.2837 40.0326C26.231 36.2585 26.231 31.7717 24.2837 27.9975L23.7515 26.9536C23.2797 26.0302 23.3601 24.8657 24.0828 24.133C24.0828 24.1229 24.0931 24.123 24.0931 24.123C24.0931 24.123 24.1031 24.1129 24.1132 24.1129C24.856 23.3902 26.0204 23.3099 26.9338 23.7817L27.9777 24.3137C31.7518 26.261 36.2386 26.261 40.0228 24.3137L41.0662 23.7817C41.9897 23.3099 43.1541 23.3902 43.8868 24.1129C43.8868 24.1129 43.8969 24.123 43.9069 24.123L43.9172 24.133C44.6399 24.8758 44.7203 26.0402 44.2485 26.9536L43.7163 27.9975C41.769 31.7717 41.769 36.2585 43.7163 40.0326L44.2485 41.0765C44.7203 41.9899 44.6499 43.1543 43.9172 43.8971Z" fill="white"/>
          </g>
          <defs>
            <filter id="filter0_di" x="0" y="0" width="68" height="68" filterUnits="userSpaceOnUse" colorInterpolationFilters="sRGB">
              <feFlood floodOpacity="0" result="BackgroundImageFix"/>
              <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
              <feMorphology radius="2" operator="dilate" in="SourceAlpha" result="effect1_dropShadow"/>
              <feOffset/>
              <feComposite in2="hardAlpha" operator="out"/>
              <feColorMatrix type="matrix" values="0 0 0 0 0.117647 0 0 0 0 0.129412 0 0 0 0 0.164706 0 0 0 0.12 0"/>
              <feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
              <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
              <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
              <feOffset dy="-1"/>
              <feGaussianBlur stdDeviation="0.5"/>
              <feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
              <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.04 0"/>
              <feBlend mode="normal" in2="shape" result="effect2_innerShadow"/>
            </filter>
            <linearGradient id="paint0_linear" x1="34" y1="2" x2="34" y2="66" gradientUnits="userSpaceOnUse">
              <stop/>
              <stop offset="1" stopColor="#677190"/>
            </linearGradient>
          </defs>
        </svg>

        {user ? (
          <>
            <h1 className="text-[17px] font-bold text-gray-900 tracking-tight">Your account</h1>
            <div className="w-full h-px bg-gray-100" />
            <Profile />
            <LogoutButton />
          </>
        ) : (
          <>
            <h1 className="text-[17px] font-bold text-gray-900 tracking-tight">Welcome to Sample0</h1>
            <p className="text-[13px] text-gray-400 text-center leading-relaxed -mt-2">
              Get started by logging in to your account
            </p>
            <div className="h-3" />
            <LoginButton />
          </>
        )}
      </div>

      <div className="flex items-center gap-1.5 text-[11px] text-gray-400">
        <span>Powered by</span>
        <img
          src="https://cdn.auth0.com/quantum-assets/dist/latest/logos/auth0/auth0-lockup-en-onlight.svg"
          alt="Auth0"
          className="h-3 opacity-40"
        />
      </div>
    </main>
  );
}
9

Mettre à jour la structure de la page avec Auth0Provider

Mettez à jour src/app/layout.tsx pour charger la police Inter et entourer votre application de Auth0Provider :
src/app/layout.tsx
import { Inter } from "next/font/google";
import type { Metadata } from "next";
import { Auth0Provider } from "@auth0/nextjs-auth0/client";
import "./globals.css";

const inter = Inter({
  subsets: ["latin"],
  weight: ["300", "400", "500", "600", "700"],
});

export const metadata: Metadata = {
  title: "Auth0 Next.js App",
  description: "Next.js app with Auth0 authentication",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <Auth0Provider>{children}</Auth0Provider>
      </body>
    </html>
  );
}
Dans la version 4, Auth0Provider est facultatif. Vous en avez seulement besoin si vous souhaitez transmettre un utilisateur initial pendant le rendu côté serveur afin qu’il soit disponible pour le hook useUser().
10

Configurer Tailwind CSS

Remplacez le contenu de src/app/globals.css par ce qui suit :
src/app/globals.css
@import "tailwindcss";
11

Lancez votre application

npm run dev
Votre application sera accessible à http://localhost:3000. Le SDK Auth0 v4 configure automatiquement les routes d’authentification sous /auth/* (et non sous /api/auth/*, comme dans la v3).Si le port 3000 est déjà utilisé, exécutez : npm run dev -- --port 3001 et mettez à jour les URL de rappel de votre application Auth0 vers http://localhost:3001
Point de contrôleVous devriez maintenant avoir une page de connexion Auth0 entièrement fonctionnelle sur votre localhost

Dépannage

Si vous voyez l’erreur JWEDecryptionFailed: decryption operation failed, elle est causée soit par une valeur AUTH0_SECRET invalide, soit par un ancien témoin de session chiffré avec un secret différent.Solution :
  1. Générez un nouveau secret avec :
openssl rand -hex 32
  1. Mettez à jour votre fichier .env.local :
AUTH0_SECRET=<your-new-64-character-hex-string>
  1. Supprimez les témoins de votre navigateur pour localhost:3000 :
    • Chrome/Edge : Appuyez sur F12 → onglet Application → Cookies → Supprimez tous les cookies pour localhost
    • Firefox : Appuyez sur F12 → onglet Storage → Cookies → Supprimez tous les cookies pour localhost
    • Safari : menu Develop → Show Web Inspector → onglet Storage → Cookies → Delete all
  2. Redémarrez votre serveur de développement :
npm run dev
Le secret doit contenir exactement 32 octets (64 caractères hexadécimaux). Cette erreur se produit lorsque l’application tente de déchiffrer un témoin de session existant qui a été chiffré avec un secret différent.
Si le clic sur login vous redirige vers une page 404, vérifiez ces problèmes courants :
  1. Emplacement du proxy : Assurez-vous que src/proxy.ts se trouve au bon endroit
  2. Code du proxy : Vérifiez que le proxy correspond au code de l’étape 6
  3. Redémarrage du serveur : Après avoir créé le fichier proxy, redémarrez le serveur de développement
  4. Vérification des importations : Assurez-vous que le chemin import { auth0 } from "./lib/auth0" est correct
Si vous voyez « Cannot find module ’@/components/LoginButton’ » ou une erreur semblable :
  1. Vérifiez que les fichiers existent : Assurez-vous que tous les fichiers de l’étape 3 ont été créés
  2. Vérifiez les chemins : Assurez-vous que les composants se trouvent dans le répertoire src/components/
  3. Redémarrez TypeScript : Appuyez sur Cmd+Shift+P (Mac) ou Ctrl+Shift+P (Windows), puis exécutez « TypeScript: Restart TS Server »
  4. Vérifiez les importations : Assurez-vous d’utiliser @/components/* (et non ~/components/*)

Utilisation avancée

Ce guide de démarrage rapide utilise Auth0 Next.js SDK v4, qui apporte d’importants changements par rapport à la v3 :
  • Aucun gestionnaire de route dynamique requis - Les routes d’authentification sont montées automatiquement par le proxy
  • Configuration simplifiée de l’application - new Auth0Client() lit automatiquement les variables d’environnement
  • Nouveaux chemins de route - Les routes se trouvent sous /auth/* plutôt que sous /api/auth/*
  • Proxy requis - Toutes les fonctionnalités d’authentification passent par proxy.ts
  • Utilisez des balises <a> - La navigation doit utiliser <a href="/auth/login"> plutôt que des boutons avec onClick

Routes d’authentification

Le SDK monte automatiquement ces routes via le proxy :
RouteObjectif
/auth/loginLancer la connexion
/auth/logoutDéconnecter l’utilisateur
/auth/callbackTraiter le callback Auth0
/auth/profileObtenir le profil de l’utilisateur
/auth/access-tokenObtenir le jeton d’accès
/auth/backchannel-logoutTraiter la déconnexion backchannel
Si vous obtenez des erreurs 404 sur ces routes, assurez-vous que :
  1. Le fichier proxy.ts se trouve au bon endroit (à la racine du projet, ou dans src/ si vous utilisez un répertoire src/)
  2. Le proxy est correctement configuré avec le motif matcher indiqué à l’étape 6
  3. Le serveur de développement a été redémarré après la création du fichier proxy
Auth0 Next.js SDK v4 prend en charge les modèles App Router et Pages Router. Voici quelques modèles courants côté serveur :
app/protected/page.tsx
import { auth0 } from "@/lib/auth0";
import { redirect } from "next/navigation";

export default async function ProtectedPage() {
  const session = await auth0.getSession();

  if (!session) {
    redirect('/auth/login');
  }

  return (
    <div>
      <h1>Protected Content</h1>
      <p>Welcome, {session.user.name}!</p>
    </div>
  );
}
Pour gérer l’état d’authentification côté client, utilisez le hook useUser :
components/UserProfile.tsx
"use client";

import { useUser } from "@auth0/nextjs-auth0/client";

export default function UserProfile() {
  const { user, error, isLoading } = useUser();

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;
  if (!user) return <div>Not logged in</div>;

  return (
    <div>
      <h2>{user.name}</h2>
      <p>{user.email}</p>
      <img src={user.picture} alt="Profile" referrerPolicy="no-referrer" />
    </div>
  );
}
Pour protéger les routes d’API, utilisez la méthode withApiAuthRequired :
app/api/protected/route.ts
import { auth0 } from "@/lib/auth0";

export const GET = auth0.withApiAuthRequired(async function handler() {
  const session = await auth0.getSession();

  return Response.json({
    message: "This is a protected API route",
    user: session?.user
  });
});
Si vous utilisez un service backend tiers (comme Convex, Supabase ou Firebase) qui exige des jetons d’authentification Auth0, vous devrez transmettre le jeton d’accès de votre application Next.js au client backend.

Obtention du jeton d’accès

Côté serveur (App Router) :
app/api/token/route.ts
import { auth0 } from "@/lib/auth0";
import { NextResponse } from "next/server";

export async function GET() {
  const session = await auth0.getSession();

  if (!session) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const accessToken = session.accessToken;
  return NextResponse.json({ accessToken });
}
Côté client :
lib/convex-client.ts
"use client";

import { ConvexProviderWithAuth0 } from "convex/react-auth0";
import { ConvexReactClient } from "convex/react";

const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!);

export function ConvexClientProvider({ children }: { children: React.ReactNode }) {
  return (
    <ConvexProviderWithAuth0
      client={convex}
      useAuth0={() => ({
        // Récupérer le jeton d’accès depuis votre route d’API Next.js
        getAccessToken: async () => {
          const response = await fetch("/api/token");
          const { accessToken } = await response.json();
          return accessToken;
        },
      })}
    >
      {children}
    </ConvexProviderWithAuth0>
  );
}

Configuration de votre backend

La plupart des services tiers ont besoin de votre Domaine Auth0 et de votre audience pour vérifier les jetons. Dans la configuration de votre backend :
convex/auth.config.ts
export default {
  providers: [
    {
      domain: process.env.AUTH0_DOMAIN,
      applicationID: process.env.AUTH0_CLIENT_ID,
    },
  ],
};
Assurez-vous que votre application Auth0 est configurée avec une audience d’API si votre backend l’exige. Vous pouvez la définir dans Auth0 Dashboard, sous Applications → APIs, ou ajouter AUTH0_AUDIENCE à votre fichier .env.local et configurer le SDK en conséquence.

Résolution des problèmes liés aux jetons

Si ctx.auth.getUserIdentity() renvoie null dans votre backend :
  1. Vérifiez que le jeton est bien transmis : Consultez l’onglet Réseau des outils de développement du navigateur pour confirmer que le jeton est inclus dans les requêtes
  2. Vérifiez le format du jeton : Assurez-vous de transmettre le accessToken, et non le idToken
  3. Vérifiez la configuration du backend : Confirmez que votre backend utilise le bon Domaine Auth0 et le bon ID client
  4. Vérifiez l’audience : Si vous utilisez une API Auth0, assurez-vous que AUTH0_AUDIENCE est défini et correspond à votre identifiant d’API
  5. Inspectez les claims du jeton : Décodez votre JWT sur jwt.io pour vérifier qu’il contient les claims attendues