Permisos (permission-first)¶
Objetivo: agregar un permiso nuevo, sembrarlo, proteger rutas y exponerlo al frontend (Inertia) vía auth.can
.
1) Declarar permisos por módulo¶
- Archivo por módulo en
config/permissions/<modulo>.php
.
<?php
return [
'permissions' => [
'<modulo>.index', '<modulo>.view', '<modulo>.create', '<modulo>.update', '<modulo>.delete',
],
'descriptions' => [
'<modulo>.index' => 'Listar <modulo>',
'<modulo>.view' => 'Ver <modulo>',
// ...
],
];
2) Agregador de permisos (ya incluido)¶
config/permissions.php
fusiona todos los módulos:
<?php
$permissions = $descriptions = [];
foreach (glob(__DIR__.'/permissions/*.php') as $file) {
$data = require $file;
$permissions = array_merge($permissions, $data['permissions'] ?? []);
$descriptions = array_merge($descriptions, $data['descriptions'] ?? []);
}
return [
'guard' => 'web',
'permissions' => array_values(array_unique($permissions)),
'descriptions' => $descriptions,
];
3) Sembrar y sincronizar¶
php artisan config:clear
php artisan db:seed --class=Database\\Seeders\\PermissionsSeeder
4) Proteger rutas¶
Usa middleware can:<permiso>
o, si prefieres Spatie directamente, permission:<permiso>
.
Route::get('settings/profile', [ProfileController::class, 'edit'])
->middleware('can:settings.profile.view')
->name('profile.edit');
Laravel 12 + Spatie: registrar aliases de middleware de ruta¶
En Laravel 12 ya no existe Http/Kernel.php
. Si vas a usar permission:
/role:
en rutas, registra los aliases en bootstrap/app.php
:
use Spatie\Permission\Middleware\PermissionMiddleware;
use Spatie\Permission\Middleware\RoleMiddleware;
use Spatie\Permission\Middleware\RoleOrPermissionMiddleware;
// ...
->withMiddleware(function (Middleware $middleware) {
// ...
$middleware->alias([
'role' => RoleMiddleware::class,
'permission' => PermissionMiddleware::class,
'role_or_permission' => RoleOrPermissionMiddleware::class,
]);
});
Luego puedes proteger rutas así:
Route::get('/roles', [RolesController::class, 'index'])
->middleware('permission:roles.view')
->name('roles.index');
Nota: si no registras los aliases verás el error: "Target class [permission] does not exist.".
5) Frontend (Inertia)¶
app/Http/Middleware/HandleInertiaRequests.php
comparteauth.can
(mapa permiso => booleano).- En React:
if (!page.props.auth.can['users.create']) return null;
6) Tests recomendados¶
tests/Feature/Permissions/PermissionsBehaviorTest.php
tests/Feature/Infrastructure/InertiaSharedPropsTest.php
Con estos tests, si agregas un permiso en config/permissions/
, se valida que:
- El frontend reciba la llave en
auth.can
. - Las rutas protegidas respondan según corresponda.