Guide d'intégration Better Auth
Consultez toujours better-auth.com/docs pour des exemples de code et l'API la plus récente.
Workflow de configuration
- Installer :
npm install better-auth - Définir les variables d'env :
BETTER_AUTH_SECRETetBETTER_AUTH_URL - Créer
auth.tsavec base de données + config - Créer un gestionnaire de route pour votre framework
- Exécuter
npx @better-auth/cli@latest migrate - Vérifier : appeler
GET /api/auth/ok— doit retourner{ status: "ok" }
Référence rapide
Variables d'environnement
BETTER_AUTH_SECRET- Secret de chiffrement (min 32 caractères). Générer :openssl rand -base64 32BETTER_AUTH_URL- URL de base (ex.https://example.com)
Ne définissez baseURL/secret dans la config que si les variables d'env ne sont PAS définies.
Emplacement des fichiers
La CLI cherche auth.ts dans : ./, ./lib, ./utils, ou sous ./src. Utilisez --config pour un chemin personnalisé.
Commandes CLI
npx @better-auth/cli@latest migrate- Appliquer le schéma (adaptateur intégré)npx @better-auth/cli@latest generate- Générer le schéma pour Prisma/Drizzlenpx @better-auth/cli mcp --cursor- Ajouter MCP aux outils IA
Relancez après l'ajout ou la modification de plugins.
Options de config principales
| Option | Notes |
|---|---|
appName |
Nom d'affichage optionnel |
baseURL |
Seulement si BETTER_AUTH_URL n'est pas défini |
basePath |
Par défaut /api/auth. Définir / pour la racine. |
secret |
Seulement si BETTER_AUTH_SECRET n'est pas défini |
database |
Requis pour la plupart des fonctionnalités. Voir la doc des adaptateurs. |
secondaryStorage |
Redis/KV pour les sessions et les rate limits |
emailAndPassword |
{ enabled: true } pour activer |
socialProviders |
{ google: { clientId, clientSecret }, ... } |
plugins |
Tableau de plugins |
trustedOrigins |
Liste blanche CSRF |
Base de données
Connexions directes : Passer une instance pg.Pool, pool mysql2, better-sqlite3, ou bun:sqlite.
Adaptateurs ORM : Importer depuis better-auth/adapters/drizzle, better-auth/adapters/prisma, better-auth/adapters/mongodb.
Critique : Better Auth utilise les noms de modèle de l'adaptateur, PAS les noms de table sous-jacents. Si le modèle Prisma est User mappé à la table users, utilisez modelName: "user" (référence Prisma), pas "users".
Gestion des sessions
Priorité de stockage :
- Si
secondaryStoragedéfini → les sessions y vont (pas en BD) - Définir
session.storeSessionInDatabase: truepour aussi persister en BD - Pas de base de données +
cookieCache→ mode entièrement sans état
Stratégies de cache cookie :
compact(par défaut) - Base64url + HMAC. Plus petit.jwt- JWT standard. Lisible mais signé.jwe- Chiffré. Sécurité maximale.
Options clés : session.expiresIn (défaut 7 jours), session.updateAge (intervalle de rafraîchissement), session.cookieCache.maxAge, session.cookieCache.version (changer pour invalider toutes les sessions).
Config utilisateur et compte
Utilisateur : user.modelName, user.fields (mapping de colonnes), user.additionalFields, user.changeEmail.enabled (désactivé par défaut), user.deleteUser.enabled (désactivé par défaut).
Compte : account.modelName, account.accountLinking.enabled, account.storeAccountCookie (pour OAuth sans état).
Requis pour l'inscription : champs email et name.
Flux d'e-mail
emailVerification.sendVerificationEmail- Doit être défini pour que la vérification fonctionneemailVerification.sendOnSignUp/sendOnSignIn- Déclencheurs d'envoi automatiqueemailAndPassword.sendResetPassword- Gestionnaire d'e-mail de réinitialisation de mot de passe
Sécurité
Dans advanced :
useSecureCookies- Forcer les cookies HTTPSdisableCSRFCheck- ⚠️ Risque de sécuritédisableOriginCheck- ⚠️ Risque de sécuritécrossSubDomainCookies.enabled- Partager les cookies entre sous-domainesipAddress.ipAddressHeaders- En-têtes IP personnalisés pour les proxiesdatabase.generateId- Génération d'ID personnalisée ou"serial"/"uuid"/false
Rate limiting : rateLimit.enabled, rateLimit.window, rateLimit.max, rateLimit.storage ("memory" | "database" | "secondary-storage").
Hooks
Hooks d'endpoint : hooks.before / hooks.after - Tableau de { matcher, handler }. Utilisez createAuthMiddleware. Accédez à ctx.path, ctx.context.returned (après), ctx.context.session.
Hooks de base de données : databaseHooks.user.create.before/after, idem pour session, account. Utile pour ajouter des valeurs par défaut ou des actions post-création.
Contexte du hook (ctx.context) : session, secret, authCookies, password.hash()/verify(), adapter, internalAdapter, generateId(), tables, baseURL.
Plugins
Importer depuis des chemins dédiés pour le tree-shaking :
import { twoFactor } from "better-auth/plugins/two-factor"
PAS from "better-auth/plugins".
Plugins populaires : twoFactor, organization, passkey, magicLink, emailOtp, username, phoneNumber, admin, apiKey, bearer, jwt, multiSession, sso, oauthProvider, oidcProvider, openAPI, genericOAuth.
Les plugins client vont dans createAuthClient({ plugins: [...] }).
Client
Importer depuis : better-auth/client (vanilla), better-auth/react, better-auth/vue, better-auth/svelte, better-auth/solid.
Méthodes clés : signUp.email(), signIn.email(), signIn.social(), signOut(), useSession(), getSession(), revokeSession(), revokeSessions().
Sécurité des types
Inférer les types : typeof auth.$Infer.Session, typeof auth.$Infer.Session.user.
Pour des projets client/serveur séparés : createAuthClient<typeof auth>().
Pièges courants
- Nom du modèle vs table - La config utilise le nom du modèle ORM, pas le nom de la table BD
- Schéma du plugin - Relancer la CLI après l'ajout de plugins
- Stockage secondaire - Les sessions y vont par défaut, pas en BD
- Cache cookie - Les champs de session personnalisés ne sont PAS en cache, toujours rechargés
- Mode sans état - Pas de BD = session dans le cookie uniquement, déconnexion à l'expiration du cache
- Flux de changement d'e-mail - Envoie d'abord à l'e-mail actuel, puis au nouvel e-mail