Files
core/src/features/auth/GUIDE-custom-login.md
T

3.2 KiB

Pages d'authentification personnalisées

Pour utiliser sa propre mise en page, on crée des routes Next.js qui enveloppent les composants Zen dans un layout.

Chaque page suit le même patron : un composant serveur qui charge la session et passe les actions, et un wrapper client qui gère la navigation.

  • Composants : @zen/core/features/auth/pages
  • Actions : @zen/core/features/auth/actions

Composants disponibles

Page Composant Props principales
Connexion LoginPage onSubmit, onSetSessionCookie, onNavigate, redirectAfterLogin, currentUser
Inscription RegisterPage onSubmit, onNavigate, currentUser
Mot de passe oublié ForgotPasswordPage onSubmit, onNavigate, currentUser
Réinitialisation ResetPasswordPage onSubmit, onNavigate, email, token
Confirmation courriel ConfirmEmailPage onSubmit, onNavigate, email, token
Déconnexion LogoutPage onLogout, onSetSessionCookie

onNavigate reçoit une valeur parmi : 'login' | 'register' | 'forgot' | 'reset'.


Exemple : page de connexion

Serveurapp/auth/login/page.js

import { getSession, loginAction, setSessionCookie } from '@zen/core/features/auth/actions';
import { LoginPageWrapper } from './LoginPageWrapper';

export default async function LoginRoute() {
  const session = await getSession();
  return (
    <MonLayout>
      <LoginPageWrapper
        loginAction={loginAction}
        setSessionCookie={setSessionCookie}
        currentUser={session?.user ?? null}
      />
    </MonLayout>
  );
}

Clientapp/auth/login/LoginPageWrapper.js

'use client';

import { useRouter } from 'next/navigation';
import { LoginPage } from '@zen/core/features/auth/pages';

export function LoginPageWrapper({ loginAction, setSessionCookie, currentUser }) {
  const router = useRouter();
  return (
    <LoginPage
      onSubmit={loginAction}
      onSetSessionCookie={setSessionCookie}
      onNavigate={(page) => router.push(`/auth/${page}`)}
      redirectAfterLogin="/"
      currentUser={currentUser}
    />
  );
}

Le même patron s'applique à toutes les autres pages. Les différences :

  • RegisterPage : passer registerAction comme onSubmit
  • ForgotPasswordPage : passer forgotPasswordAction comme onSubmit
  • ResetPasswordPage / ConfirmEmailPage : lire email et token dans searchParams et les passer en props
  • LogoutPage : utiliser onLogout au lieu de onSubmit, pas de onNavigate requis

Protection de route

import { getSession } from '@zen/core/features/auth/actions';
import { redirect } from 'next/navigation';

export default async function PageProtégée() {
  const session = await getSession();
  if (!session?.user) redirect('/auth/login');
  // ...
}

Page par défaut (sans personnalisation)

Si une mise en page personnalisée n'est pas nécessaire, on garde simplement :

// app/auth/[...auth]/page.js
export { default } from '@zen/core/features/auth/server';