Authentification
Arrel authentifie avec Sanctum en mode SPA : cookies de session protégés par CSRF, sans tokens à gérer. Sur cette base, il y a trois couches facultatives : la vérification de l'e-mail, un second facteur et les notifications de la cloche.
Configurer Sanctum
L'application doit ajouter le domaine du panneau à sanctum.stateful (et, en développement, l'origine du serveur Vite si vous travaillez en mode dev) :
config([
'sanctum.stateful' => array_merge(
config('sanctum.stateful', []),
['votre-domaine.test', 'localhost:5173'],
),
]);L'API d'authentification vit sous /arrel/api/, quel que soit le préfixe du panneau :
| Route | Ce qu'elle fait |
|---|---|
POST /arrel/api/login | Ouvre la session avec email et password. |
POST /arrel/api/login/two-factor | Résout le second facteur d'une connexion en attente. |
POST /arrel/api/logout | Ferme la session. |
GET /arrel/api/user | L'utilisateur authentifié. |
Le reste de l'API est derrière auth:sanctum, la vérification de l'e-mail et le second facteur.
Limites de tentatives
- La connexion admet cinq tentatives échouées par combinaison d'e-mail et d'adresse IP. Au-delà de la limite, la réponse est une erreur de validation avec le message
arrel::auth.throttle. - Une connexion qui attend le second facteur expire au bout de cinq minutes, ou après cinq codes incorrects. L'utilisateur doit saisir à nouveau l'e-mail et le mot de passe.
- Les endpoints de login ont en plus une limite de 10 requêtes par minute au niveau de la route.
Vérification de l'e-mail
Si le modèle d'utilisateur implémente Illuminate\Contracts\Auth\MustVerifyEmail, le panneau ne s'ouvre pas tant que l'e-mail n'est pas vérifié. Tant qu'il ne l'est pas, l'API répond 403 avec email_verification_required: true et la SPA affiche l'écran de vérification, avec un bouton pour envoyer l'e-mail (limité à trois par minute).
final class User extends Authenticatable implements MustVerifyEmail
{
// ...
}Le lien de l'e-mail est une URL signée et temporaire. Elle expire selon auth.verification.expire (60 minutes par défaut), pointe vers arrel.email.verify et, une fois vérifié, redirige à nouveau vers le panneau. Un utilisateur qui n'implémente pas MustVerifyEmail ne passe jamais par cette étape.
Second facteur
Arrel ne fournit aucune implémentation TOTP propre. Il définit le contrat Arrel\Auth\TwoFactorAuthenticator et vous liez celle que vous voulez (un paquet de 2FA, une implémentation propre sur un secret chiffré...).
namespace Arrel\Auth;
interface TwoFactorAuthenticator
{
public function isEnabledFor(Authenticatable $user): bool;
public function isRequiredFor(Authenticatable $user): bool;
public function verify(Authenticatable $user, string $code): bool;
public function newSecret(): string;
public function qrCode(Authenticatable $user, string $secret): string;
public function verifySetup(string $secret, string $code): bool;
/** @return list<string> Les codes de récupération, à afficher une seule fois. */
public function enable(Authenticatable $user, string $secret): array;
public function disable(Authenticatable $user): void;
}| Méthode | Quand elle est appelée |
|---|---|
isEnabledFor() | À la connexion, pour décider s'il faut demander un code. |
isRequiredFor() | Pour obliger un utilisateur précis à l'activer avant d'entrer dans le panneau (par exemple, selon son rôle). |
verify() | En validant le code de la connexion. Elle doit aussi accepter un code de récupération. |
newSecret(), qrCode() | Au début de l'activation. qrCode() retourne l'image que la SPA affiche telle quelle. |
verifySetup() | À la confirmation de l'activation, avec le secret encore en attente dans la session. |
enable() | Une fois confirmé. Enregistre le secret et retourne les codes de récupération. |
disable() | À la désactivation. |
Pour l'activer, liez votre implémentation dans le conteneur :
// AppServiceProvider::register()
$this->app->bind(TwoFactorAuthenticator::class, TotpAuthenticator::class);Sans aucune liaison, le second facteur n'existe pas : il n'y a aucune étape supplémentaire ni aucune page de sécurité à utiliser.
Ce que voit l'utilisateur
- À la connexion, si
isEnabledFor()est vrai, la réponse est{ "two_factor": true }et la SPA demande le code. - La page de sécurité (
/{prefix}/{panel}/security) permet de l'activer et de le désactiver. À l'activation, elle affiche le QR, demande un premier code et, une fois confirmé, affiche les codes de récupération une seule fois. - Si
isRequiredFor()est vrai et que l'utilisateur ne l'a pas encore activé, toute l'API répond 403 avectwo_factor_setup_required: trueet la SPA le conduit à la page de sécurité. Les endpoints de la page de sécurité elle-même restent accessibles. - Un utilisateur pour qui il est obligatoire ne peut pas le désactiver : l'endpoint répond 403 avec
arrel::auth.required_cannot_disable.
Les endpoints sont GET et DELETE /arrel/api/two-factor, POST /arrel/api/two-factor/setup et POST /arrel/api/two-factor/confirm. La confirmation et la désactivation sont limitées à 10 requêtes par minute.
Middleware avant et après l'utilisateur
config('arrel.middleware') s'exécute avant que Sanctum ne résolve la session : c'est l'endroit pour identifier le tenant. config('arrel.authenticated_middleware') s'exécute après la vérification de l'e-mail et le second facteur, avec l'utilisateur déjà résolu. Voir Configuration.
Notifications
La cloche du panneau lit les notifications de base de données de Laravel de l'utilisateur authentifié. Rien de spécifique à Arrel n'est nécessaire : une notification qui utilise le canal database et stocke ces clés dans data suffit :
final class PostPublished extends Notification
{
public function __construct(private readonly Post $post) {}
public function via(object $notifiable): array
{
return ['database'];
}
public function toArray(object $notifiable): array
{
return [
'title' => 'Post published',
'body' => $this->post->title,
'url' => "/arrel/admin/posts/{$this->post->id}",
];
}
}| Clé | Usage |
|---|---|
title | Titre de l'entrée. |
body | Texte facultatif sous le titre. |
url | Lien facultatif qui s'ouvre au clic sur l'entrée. |
La cloche affiche les 20 dernières notifications, le nombre de celles non lues, et permet d'en marquer une ou toutes comme lues. Chaque utilisateur ne voit et ne modifie que les siennes.
Étape suivante
Pour décider qui peut faire quoi dans le panneau, voir Sécurité et autorisation.