Как перехватить исключение Laravel Sanctum MissingAbilityException и получить доступ к соответствующей отсутствующей споPhp

Кемеровские программисты php общаются здесь
Ответить
Anonymous
 Как перехватить исключение Laravel Sanctum MissingAbilityException и получить доступ к соответствующей отсутствующей спо

Сообщение Anonymous »

Я работаю над приложением Laravel 11 и использую функциональность токенов API Sanctum (без SPA, без сеанса, без CSRF и т. д., REST API и токены, маршруты в api.php, а не в web.php). ). Все работает хорошо — я могу выдавать токены и использовать их для доступа к маршрутам, защищенным промежуточным программным обеспечением auth:sanctum. Сейчас я добавляю возможности к токенам и использую промежуточное программное обеспечение способностей для управления доступом к некоторым маршрутам.
Я добавил необходимые псевдонимы промежуточного программного обеспечения в bootstrap/app.php:

Код: Выделить всё

$middleware->alias([
...
'abilities' => \Laravel\Sanctum\Http\Middleware\CheckAbilities::class,
'ability' => \Laravel\Sanctum\Http\Middleware\CheckForAnyAbility::class,
]);
И добавил проверку возможностей маршрута в маршруты/api.php:

Код: Выделить всё

Route::middleware(['auth:sanctum', 'abilities:foo'])->group(function () {
Route::get('/foo', [FooController::class, 'foo']);
});
Теперь я генерирую токен без каких-либо способностей:

Код: Выделить всё

$token_without_abilities = $user->createToken('name', [], Carbon::now()->addMinutes(10))->plainTextToken;
Когда я пытаюсь получить доступ к маршруту /foo, описанному выше, используя этот токен, который не включает необходимую способность foo, я ожидаю, что это потерпит неудачу, и конечно же, выдается исключение. Согласно источнику, в \Laravel\Sanctum\Http\Middleware\CheckAbilities должно быть выброшено MissingAbilityException. Я добавил немного журнала отладки и убедился, что это действительно то, что происходит, я достиг конструктора MissingAbilityException и могу зарегистрировать отсутствующую способность как $ability в этот момент.
Я хочу перехватить это исключение и вернуть ответ JSON с правильным сообщением об ошибке, поэтому я добавил следующее в свой bootstrap/app.php:

Код: Выделить всё

use Laravel\Sanctum\Exceptions\MissingAbilityException;

->withExceptions(function (Exceptions $exceptions) {
$exceptions->render(function (MissingAbilityException $exception, Request $request) {
Log::debug('MissingAbilityException exception: ' . printr_r($exception->abilities(), true);

return response()->json([
'message' => 'Missing ability ' . $exception->getMessage(),
]);
});
});
Но исключение не перехватывается, вместо этого выдается исключение AccessDeniedHttpException, и в итоге получается:

Код: Выделить всё

{
"message": "Invalid ability provided.",
"exception": "Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException",
"file": "/var/www/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php",
"line": 633,
"trace": [
{
"file": "/var/www/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php",
"line": 577,
"function": "prepareException",
"class": "Illuminate\\Foundation\\Exceptions\\Handler",
"type": "->"
},
{
"file": "/var/www/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
"line": 51,
"function": "render",
"class": "Illuminate\\Foundation\\Exceptions\\Handler",
"type": "->"
},
...
Полная трассировка стека.
Единственный намек, который я могу найти по этому поводу, — это ответ на проблему Github, задающую более или менее то же самое, что и я. Этот ответ предполагает то, что я уже делаю, AFAICT, хотя и в синтаксисе до версии Laravel 11.
Если я попытаюсь перехватить исключение AccessDeniedHttpException в bootstrap/app.php таким же образом, это работает, но я больше не могу получить доступ к отсутствующей способности, $Exception->abilities(); дает мне вызов неопределенного метода.
Как я могу перехватить исключение MissingAbilityException и получить доступ к фактической отсутствующей способности? Цель состоит в том, чтобы вернуть клиенту ответ JSON с сообщением типа «У вас нет разрешения «foo»».

Подробнее здесь: https://stackoverflow.com/questions/790 ... associated
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Php»