Authentification

Créer le compte administrateur à la première configuration, comprendre les pages fournies et la vérification du courriel, lire la session et protéger une route.

Toute authentification passe par features/auth. Le projet généré expose déjà les pages : il n'y a rien à câbler pour démarrer.

Les pages fournies

Une seule route catch-all sert tout, déjà présente dans le projet :

// app/(auth)/auth/[...auth]/page.js
export { default, generateMetadata } from '@lrvo/core/features/auth/server';
RoutePage
/auth/loginConnexion
/auth/registerInscription
/auth/forgotMot de passe oublié
/auth/resetRéinitialisation
/auth/confirmVérification de l'adresse
/auth/setupConfiguration du compte après invitation
/auth/logoutDéconnexion

La page de connexion livrée par le core

Tant que la base ne contient aucun compte, toutes ces routes affichent à la place le formulaire de première configuration, décrit ci-dessous.

Les sept pages partagent cette mise en page : une carte centrée, sans en-tête ni pied de page. C'est volontaire, le projet hôte décide de ce qui l'entoure. Pour l'envelopper dans une mise en page maison, voir Personnaliser la connexion.

Créer le compte administrateur

Après npx lrvo-db init et npm run dev, ouvrir http://localhost:3000/auth.

Tant qu'aucun compte n'existe, n'importe quelle page /auth/* affiche le formulaire Première configuration : nom, courriel, mot de passe. La redirection de /admin vers /auth/login y mène aussi. À la soumission :

  • le compte reçoit le rôle admin ;
  • son courriel est marqué vérifié, sans envoi de courriel ;
  • la session est ouverte et le navigateur part vers /admin.

Le formulaire disparaît dès que ce compte existe, et les pages reprennent leur rôle normal. Deux soumissions simultanées ne créent pas deux administrateurs : la seconde reçoit « Le compte administrateur existe déjà ».

Contraintes du mot de passe : 8 à 128 caractères, au moins une majuscule, une minuscule et un chiffre.

Créer ce compte avant d'exposer le site. Tant que la base est vide, la première personne qui atteint /auth devient administrateur.

Vérification du courriel

Un compte dont le courriel n'est pas vérifié ne peut pas se connecter. Après une inscription par /auth/register, un lien valide 24 heures part par courriel. La connexion est refusée avec le message « Le courriel de ce compte n'a pas été vérifié » tant que ce lien n'a pas été suivi.

Ce message n'apparaît qu'après un mot de passe correct. Sans le mot de passe, un compte non vérifié répond comme un compte inexistant.

Quatre chemins vérifient un compte :

CheminQui
Lien reçu à l'inscription, ou renvoyé depuis la page de connexionL'utilisateur
Réinitialisation du mot de passe par le lien reçu par courrielL'utilisateur
Bouton « Marquer le courriel comme vérifié » dans la fiche de /admin/usersUn administrateur
Invitation, ou création par l'admin avec mot de passeVérifié dès la création

Le bouton « Renvoyer le lien de vérification » apparaît sous le message de refus. Sa réponse est la même que le compte existe ou non.

Les inscriptions publiques exigent un fournisseur de courriel fonctionnel. Sans lui, l'inscrit ne reçoit jamais son lien et un administrateur doit le vérifier à la main. Voir Courriels.

Une session déjà ouverte n'est pas coupée : la règle s'applique à la connexion. Un compte non vérifié qui avait une session avant la mise à jour la garde jusqu'à son expiration.

Lire la session

import { getSession } from '@lrvo/core/features/auth/actions';

export default async function Page() {
  const session = await getSession();
  if (!session?.user) return <p>Non connecté.</p>;
  return <p>Bonjour {session.user.name}</p>;
}

getSession lit le cookie et renouvelle automatiquement la session si elle expire dans moins de 20 jours. La session vaut 30 jours.

Protéger une route

Page publique réservée aux connectés

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

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

Page d'admin

import { protectAdmin } from '@lrvo/core/features/admin/protect';

export default async function PageAdmin() {
  const session = await protectAdmin();
  // l'utilisateur a la permission admin.access
}

protectAdmin redirige vers /auth/login si l'utilisateur n'est pas connecté, et vers / s'il l'est sans avoir admin.access. Les deux destinations sont configurables.

Route API

Déclarativement, dans la définition de route. Jamais dans le handler.

{ path: '/settings', method: 'PUT', handler: handleUpdate, auth: 'admin', permission: 'settings.manage' }

Voir Ajouter une route API.

Fermer les inscriptions

LRVO_AUTH_REGISTRATION=false ferme les inscriptions publiques : /auth/register affiche un message de fermeture, le lien « Pas encore de compte ? Créer un compte » disparaît de la connexion, et la server action refuse toute création même appelée directement.

Deux exceptions volontaires. Le tout premier compte reste créable tant que la base est vide, par le formulaire de première configuration, sans quoi une installation neuve ne pourrait plus créer son admin. Et la création de comptes depuis /admin/users, décrite ci-dessous, n'est pas affectée : c'est la voie prévue pour ajouter des utilisateurs une fois les inscriptions fermées.

Sans la variable, les inscriptions restent ouvertes. Détails dans Authentification.

Inviter un utilisateur

Depuis /admin/users, avec deux flux selon qu'un mot de passe est fourni.

Avec mot de passe : le compte est créé vérifié, avec un identifiant. Connexion immédiate.

Sans mot de passe : un token d'invitation valide 48 heures est généré et un courriel part. L'utilisateur suit le lien, choisit son mot de passe, et le compte est activé en une étape. Le passage par le lien vaut confirmation de l'adresse.

Ce second flux exige une configuration de courriel fonctionnelle.

Ce qui est appliqué automatiquement

Limitation de débit par IP sur première configuration, inscription, connexion, mot de passe oublié, réinitialisation, vérification et renvoi du lien. Derrière un reverse proxy, renseigner LRVO_TRUST_PROXY avec le nombre de proxys traversés, sinon l'IP reste inconnue et la limitation est suspendue.

Champs anti-bot. Chaque formulaire embarque un honeypot et un horodatage. Une soumission de moins de 1,5 seconde, de plus de 10 minutes, ou avec le honeypot rempli est rejetée.

Cookie HttpOnly. Le token n'est jamais exposé à JavaScript.

Réponses non énumérantes. La demande de réinitialisation et le renvoi du lien de vérification répondent identiquement que le compte existe ou non.

Personnaliser la mise en page

Pour envelopper les pages dans une mise en page maison, remplacer la route catch-all par des routes individuelles. Le patron complet est dans Personnaliser la connexion.

Remplacer la mise en page ne désactive rien de la sécurité : la limitation de débit, l'anti-bot et la validation du token restent appliqués par les server actions.

Étape suivante

Structure du projet décrit ce que la génération a produit et où écrire son propre code.

Sur cette page