Documentation

Better Auth

Comment Motoko Base gère l’authentification avec Better Auth — e-mail/mot de passe, OAuth, sessions, routes protégées, vérification et gestion de compte.

Ouvrir dansChatGPT (s’ouvre dans un nouvel onglet)Claude (s’ouvre dans un nouvel onglet)Cursor (s’ouvre dans un nouvel onglet)Comment Motoko Base gère l’authentification avec Better Auth — e-mail/mot de passe, OAuth, sessions, routes protégées, vérification et gestion de compte.

Motoko Base utilise Better Auth pour l’authentification. Les sessions sont stockées dans PostgreSQL via l’adaptateur Drizzle. Il n’y a pas de service d’auth séparé — Postgres plus les variables d’environnement suffisent pour le développement local.

Les routes API d’auth sont montées sur /api/auth/*. Le dashboard exige une session vérifiée avant le rendu.

Ce qui est livré d’usine

FeatureStatusNotes
Email / password sign-upEnabledVerification required before dashboard access
Email / password sign-inEnabledRedirects unverified users to /verify-email
Google OAuthOptionalEnabled when GOOGLE_* env vars are set
GitHub OAuthOptionalEnabled when GITHUB_* env vars are set
Email verificationRequiredSent on sign-up; resend on sign-in if still unverified
Password resetEnabledRequires Resend (RESEND_API_KEY, EMAIL_FROM)
Change passwordEnabledSettings → Security; revokes other sessions
Sign outEnabledUser menu in the dashboard header
Session managementEnabledList and revoke sessions in Settings → Security
Account linkingEnabledGoogle and GitHub link to the same user when trusted

Les boutons de connexion sociale restent désactivés jusqu’à ce que les identifiants OAuth soient configurés. Voir Configuration OAuth pour la configuration pas à pas de chaque fournisseur.

E-mail et mot de passe

Sign up (/sign-up) collecte nom, e-mail et mot de passe. Better Auth crée l’utilisateur et envoie un e-mail de vérification lorsque Resend est configuré.

Parce que requireEmailVerification est activé, l’inscription ne connecte pas automatiquement l’utilisateur. Après l’inscription, ils voient un écran « Check your email » et doivent vérifier avant d’accéder à /dashboard.

Sign in (/sign-in) accepte e-mail et mot de passe. En cas de succès, le client redirige vers /dashboard. Si l’e-mail n’est pas vérifié, Better Auth renvoie 403 EMAIL_NOT_VERIFIED et le formulaire redirige vers /verify-email.

Les règles de mot de passe pour l’inscription et le changement de mot de passe sont validées dans src/features/dashboard/schemas/security.ts (MIN_PASSWORD_LENGTH = 8 par défaut).

OAuth Google et GitHub

Les deux fournisseurs sont câblés dans src/lib/auth/auth.ts et ne s’activent que lorsque les variables d’environnement sont présentes. Le client utilise authClient.signIn.social({ provider: "google" | "github" }) depuis les formulaires de sign-in et sign-up.

Les utilisateurs OAuth sont généralement marqués comme vérifiés par le fournisseur. L’account linking est activé pour Google et GitHub afin qu’un utilisateur social de retour puisse s’attacher à un compte e-mail existant lorsque Better Auth fait confiance au fournisseur.

Configuration complète du fournisseur : Configuration OAuth.

Sessions

Les sessions sont stockées dans la table session (src/lib/db/schema/auth.ts). Chaque session a un token, une expiration, une IP et un user agent.

Lectures côté serveur utilisent getCachedSession() depuis src/lib/auth/session.ts. Elle enveloppe auth.api.getSession() dans React cache() pour que layout, pages et server actions de la même requête partagent une seule lookup.

Appels côté client utilisent authClient depuis src/lib/auth/client.ts (client React Better Auth).

Exemple — vérifier la session dans un server component ou une action :

import { getCachedSession } from "@/lib/auth/session";

const session = await getCachedSession();
if (!session?.user?.id) {
  // not signed in
}

Routes protégées

Les routes du dashboard sous /dashboard sont protégées en deux couches :

  1. src/proxy.ts — gate edge pour /dashboard et /dashboard/*. Redirige les utilisateurs non authentifiés vers /sign-in et non vérifiés vers /verify-email.
  2. src/app/dashboard/layout.tsx — layout serveur qui répète les mêmes contrôles avant de rendre le shell.

Les pages individuelles et server actions appellent aussi getCachedSession() et redirigent ou renvoient des erreurs si besoin. Ce pattern de défense en profondeur garde les routes API et actions sûres même si une page oublie de vérifier.

Pour protéger une nouvelle route, placez-la sous src/app/dashboard/ (hérite layout + proxy) ou appelez getCachedSession() et redirigez manuellement.

Vérification e-mail

La vérification est obligatoire pour l’accès au dashboard.

StepWhat happens
Sign upBetter Auth sends a verification link via sendVerificationEmail
Click linkUser is verified; they can sign in
Unverified sign-inRedirect to /verify-email
Resend/verify-email calls authClient.sendVerificationEmail

La livraison d’e-mail nécessite RESEND_API_KEY et EMAIL_FROM. Sans Resend, l’app démarre mais les e-mails de vérification ne sont pas envoyés — configurez l’e-mail avant de tester l’inscription en local.

Le contenu de l’e-mail de vérification vit dans src/lib/email/templates/verification-email.tsx. Le hook d’envoi est dans src/lib/auth/auth.ts sous emailVerification.sendVerificationEmail.

Réinitialisation du mot de passe

RoutePurpose
/forgot-passwordRequest a reset link
/reset-password?token=…Set a new password from the email link

Flux :

  1. L’utilisateur soumet l’e-mail sur /forgot-password
  2. Le client appelle authClient.requestPasswordReset avec redirectTo pointant vers /reset-password
  3. Better Auth envoie l’e-mail via sendResetPassword dans auth.ts
  4. L’utilisateur ouvre le lien et soumet un nouveau mot de passe via authClient.resetPassword

Les e-mails de reset nécessitent Resend. La page forgot-password vérifie la configuration e-mail avant l’envoi.

Changer le mot de passe

Les utilisateurs connectés changent leur mot de passe dans Settings → Security (/dashboard/settings/account/security).

L’UI appelle updatePasswordAction dans src/features/dashboard/actions/security.ts, qui utilise auth.api.changePassword avec revokeOtherSessions: true — tous les autres appareils sont déconnectés après un changement réussi.

Les limites de longueur de mot de passe viennent de src/features/dashboard/schemas/security.ts.

Déconnexion

La déconnexion est déclenchée depuis le menu utilisateur du dashboard. src/features/dashboard/components/dashboard-shell.tsx appelle :

await authClient.signOut({
  fetchOptions: {
    onSuccess: () => {
      router.push("/sign-in");
      router.refresh();
    },
  },
});

Le contexte utilisateur Analytics et Sentry est effacé à la déconnexion dans le même handler.

Gestion de compte et de sessions

Profile (nom, avatar) — Settings → Profile (src/features/dashboard/components/settings/profile-settings-page.tsx).

Security (mot de passe, sessions) — Settings → Security :

  • Changer le mot de passe
  • Lister les sessions actives (navigateur, OS, dernière activité)
  • Révoquer des sessions individuelles
  • Se déconnecter de toutes les autres sessions

La logique serveur est dans src/features/dashboard/actions/security.ts (updatePasswordAction, revokeSessionAction (sessions load via src/features/dashboard/lib/security-settings.ts)).

À l’inscription, un e-mail de bienvenue est envoyé depuis le hook databaseHooks.user.create.after dans auth.ts. Lorsque Polar billing est configuré, le plugin Polar Better Auth crée un client de facturation à l’inscription (src/lib/billing/providers/polar/auth-plugin.ts).


Où modifier cela ?

Motoko Base répartit l’auth entre infrastructure serveur (src/lib/auth/), pages d’auth (src/app/…) et paramètres de compte (src/features/dashboard/components/settings/). Il n’y a pas de dossier src/features/auth/ séparé — l’UI d’auth vit dans les routes app ; la gestion de compte vit dans settings.

src/lib/auth/ — cœur auth serveur

FileChange this when you want to…
auth.tsEnable/disable providers, toggle verification, customize email hooks, add Better Auth plugins, change account linking
session.tsAdjust how server components read the session (getCachedSession)
client.tsConfigure the browser auth client (base URL is inferred automatically)
social.tsChange how Google/GitHub “configured” checks work
safe-client-error.tsEdit user-facing error messages for sign-in, sign-up, OAuth

Le handler catch-all de l’API est src/app/api/auth/[...all]/route.ts — vous avez rarement besoin de l’éditer.

Tables de base de données : src/lib/db/schema/auth.ts (user, session, account, verification).

Pages d’auth — sign-in, sign-up, récupération

PathChange this when you want to…
src/app/sign-in/Sign-in form behavior, post-login redirect, OAuth handlers
src/app/sign-up/Sign-up form, pending-verification UI
src/app/verify-email/Resend verification UX
src/app/forgot-password/Forgot-password form
src/app/reset-password/Reset-password form
src/components/ui/auth-section-3.tsxShared auth layout (fields, social buttons, styling)

Les pages sign-in et sign-up passent googleEnabled / githubEnabled depuis isGoogleAuthConfigured() et isGitHubAuthConfigured() pour que les boutons se désactivent automatiquement lorsque OAuth n’est pas configuré.

src/features/dashboard/components/settings/ — compte et sessions

FileChange this when you want to…
actions.tsPassword change, session list/revoke server actions
config.tsPassword length limits, name length limits
components/security-settings-page.tsxSecurity UI (password form, session list)
components/profile-settings-page.tsxProfile name and avatar

Route : src/app/dashboard/settings/account/security/page.tsx charge les sessions côté serveur et rend SecuritySettingsPage.

Protection des routes

FileChange this when you want to…
src/proxy.tsEdge redirects for /dashboard (session + verification gate)
src/app/dashboard/layout.tsxDashboard shell gate and user bootstrap

E-mail transactionnel (lié à l’auth)

FileChange this when you want to…
src/lib/email/index.tsVerification, reset, welcome send functions
src/lib/email/templates/verification-email.tsxVerification email content
src/lib/email/templates/password-reset-email.tsxReset email content
src/lib/email/templates/welcome-email.tsxWelcome email content
src/lib/email/templates/shared.tsxEmail brand name and layout

Variables d’environnement pour l’auth : voir Variables d’environnement.


Prochaines étapes

Configuration OAuth — Configuration pas à pas Google et GitHub.

Variables d’environnement — Référence env complète incluant BETTER_AUTH_* et clés OAuth.