Autenticació
Arrel autentica amb Sanctum en mode SPA: cookies de sessió protegides amb CSRF, sense tokens que gestionar. Sobre aquesta base hi ha tres capes opcionals: la verificació del correu, un segon factor i les notificacions de la campana.
Configurar Sanctum
L'aplicació ha d'afegir el domini del panell a sanctum.stateful (i, en desenvolupament, l'origen del servidor de Vite si hi treballes en mode dev):
config([
'sanctum.stateful' => array_merge(
config('sanctum.stateful', []),
['el-teu-domini.test', 'localhost:5173'],
),
]);L'API d'autenticació viu sota /arrel/api/, sigui quin sigui el prefix del panell:
| Ruta | Què fa |
|---|---|
POST /arrel/api/login | Inicia la sessió amb email i password. |
POST /arrel/api/login/two-factor | Resol el segon factor d'un inici de sessió pendent. |
POST /arrel/api/logout | Tanca la sessió. |
GET /arrel/api/user | L'usuari autenticat. |
La resta de l'API queda darrere auth:sanctum, la verificació del correu i el segon factor.
Límits d'intents
- L'inici de sessió admet cinc intents fallits per combinació de correu i adreça IP. Passat el límit, la resposta és un error de validació amb el missatge
arrel::auth.throttle. - Un inici de sessió que espera el segon factor caduca als cinc minuts, o després de cinc codis incorrectes. L'usuari ha de tornar a escriure correu i contrasenya.
- Els endpoints de login tenen a més un límit de 10 peticions per minut a nivell de ruta.
Verificació del correu
Si el model d'usuari implementa Illuminate\Contracts\Auth\MustVerifyEmail, el panell no s'obre fins que el correu està verificat. Mentre no ho està, l'API respon 403 amb email_verification_required: true i la SPA mostra la pantalla de verificació, amb un botó per enviar el correu (limitat a tres per minut).
final class User extends Authenticatable implements MustVerifyEmail
{
// ...
}L'enllaç del correu és una URL signada i temporal. Caduca segons auth.verification.expire (60 minuts per defecte), apunta a arrel.email.verify i, un cop verificat, redirigeix de nou al panell. Un usuari que no implementa MustVerifyEmail no passa mai per aquest pas.
Segon factor
Arrel no porta cap implementació de TOTP pròpia. Defineix el contracte Arrel\Auth\TwoFactorAuthenticator i tu hi enllaces la que vulguis (un paquet de 2FA, una implementació pròpia sobre un secret xifrat...).
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> Els codis de recuperació, per mostrar-los un sol cop. */
public function enable(Authenticatable $user, string $secret): array;
public function disable(Authenticatable $user): void;
}| Mètode | Quan es crida |
|---|---|
isEnabledFor() | A l'inici de sessió, per decidir si cal demanar un codi. |
isRequiredFor() | Per obligar un usuari concret a activar-lo abans d'entrar al panell (per exemple, segons el seu rol). |
verify() | En validar el codi de l'inici de sessió. Ha d'acceptar també un codi de recuperació. |
newSecret(), qrCode() | En començar l'activació. qrCode() retorna la imatge que la SPA mostra tal qual. |
verifySetup() | En confirmar l'activació, amb el secret encara pendent a la sessió. |
enable() | Un cop confirmat. Desa el secret i retorna els codis de recuperació. |
disable() | En desactivar-lo. |
Per activar-lo, enllaça la teva implementació al contenidor:
// AppServiceProvider::register()
$this->app->bind(TwoFactorAuthenticator::class, TotpAuthenticator::class);Sense cap enllaç, el segon factor no existeix: no hi ha cap pas addicional ni cap pàgina de seguretat que fer servir.
Com ho veu l'usuari
- A l'inici de sessió, si
isEnabledFor()és cert, la resposta és{ "two_factor": true }i la SPA demana el codi. - La pàgina de seguretat (
/{prefix}/{panel}/security) permet activar-lo i desactivar-lo. En activar-lo mostra el QR, demana un primer codi i, un cop confirmat, mostra els codis de recuperació una única vegada. - Si
isRequiredFor()és cert i l'usuari encara no l'ha activat, tota l'API respon 403 ambtwo_factor_setup_required: truei la SPA el porta a la pàgina de seguretat. Els endpoints de la pròpia pàgina de seguretat segueixen accessibles. - Un usuari per al qual és obligatori no pot desactivar-lo: l'endpoint respon 403 amb
arrel::auth.required_cannot_disable.
Els endpoints són GET i DELETE /arrel/api/two-factor, POST /arrel/api/two-factor/setup i POST /arrel/api/two-factor/confirm. La confirmació i la desactivació tenen un límit de 10 peticions per minut.
Middleware abans i després de l'usuari
config('arrel.middleware') s'executa abans que Sanctum resolgui la sessió: és el lloc per identificar el tenant. config('arrel.authenticated_middleware') s'executa després de la verificació del correu i del segon factor, amb l'usuari ja resolt. Vegeu Configuració.
Notificacions
La campana del panell llegeix les notificacions de base de dades de Laravel de l'usuari autenticat. No cal res d'específic d'Arrel: n'hi ha prou amb una notificació que usi el canal database i guardi aquestes claus a data:
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}",
];
}
}| Clau | Ús |
|---|---|
title | Títol de l'entrada. |
body | Text opcional sota el títol. |
url | Enllaç opcional que s'obre en clicar l'entrada. |
La campana mostra les 20 últimes notificacions, el nombre de les no llegides, i permet marcar-ne una o totes com a llegides. Cada usuari només veu i modifica les seves.
Següent pas
Per decidir qui pot fer què dins del panell, vegeu Seguretat i autorització.