// routes/api.php
Route::middleware('auth:sanctum')->group(function () {
Route::apiResource('licenses', LicenseController::class)
->only(['index', 'store', 'destroy']);
});
Una petición sin un token válido nunca llega al controlador. Recibe un 401:
{
"message": "Unauthenticated."
}
Esa respuesta es JSON gracias a la única línea que el Capítulo 2 añadió a bootstrap/app.php. Y dentro de la aplicación, el consumidor está donde Laravel pone siempre a la parte autenticada:
$consumer = $request->user();
Ni un atributo de request a medida, ni un helper propio. Las Policies, los limitadores de peticiones y el logging lo encuentran ahí.
Autorización: lo que un token puede hacer
La autenticación responde a «¿quién es?». La autorización responde a «¿puede hacer eso?». Una forma habitual de que una API tenga fugas es un endpoint que comprobó lo primero y olvidó lo segundo.
Sanctum trae un middleware que comprueba las habilidades de un token. Dale un alias:
// bootstrap/app.php
->withMiddleware(function (Middleware $middleware): void {
$middleware->alias([
'ability' => CheckForAnyAbility::class,
]);
})
alias() recibe la lista completa. Una segunda llamada reemplaza a la primera, así que los capítulos posteriores añaden sus alias a este array y nunca vuelven a llamarlo.
Después di, en el controlador, lo que necesita cada acción:
// app/Http/Controllers/LicenseController.php
#[Middleware('ability:licenses:read', only: ['index'])]
#[Middleware('ability:licenses:write', except: ['index'])]
class LicenseController
{
// ...
}
Un token sin la habilidad recibe un 403. La documentación de Laravel suele mostrar estos atributos sobre métodos individuales, y así se leen bien. Aquí los pongo sobre la clase por el except: una acción nueva que se añada a este controlador necesita licenses:write salvo que alguien diga lo contrario a propósito. Dentro de este controlador, lo que no se declara queda cerrado. (Documentación de Laravel: Sanctum › Token Abilities y Controllers › Controller Middleware.)
Ese valor por defecto termina en el borde del controlador. Un controlador nuevo empieza sin ninguna habilidad, protegido solo por auth:sanctum, y así es exactamente como se abren los peores agujeros de una API. El Capítulo 5 añade dos controladores y muestra lo que necesita cada uno, y el Capítulo 19 convierte «todo controlador declara quién puede llamarlo» en algo que se comprueba.
Para una acción con FormRequest, la comprobación puede vivir en authorize(), el método que el Capítulo 2 dejó devolviendo true:
// app/Http/Requests/StoreLicenseRequest.php
public function authorize(): bool
{
return $this->user()->tokenCan('licenses:write');
}
Usa una forma o la otra para una acción dada, no las dos.
Cuando las habilidades no bastan
Las habilidades dicen lo que un token puede hacer. No dicen a qué registros puede hacérselo. Esa segunda pregunta necesita una Policy, y el Capítulo 5 escribe una, para el primer recurso de esta API en el que importa. Las licencias no la necesitan, por la razón que explica la sección siguiente.