Ошибка "Target [Lcobucci\\JWT\\Parser] is not instantiable while building [App\\Containers\\Authentication\\Actions\\LogoutAction]." возникла при работе с Laravel Passport и использовании его в рамках архитектурного паттерна Porto на laravel 11. Нужно было распарсить $id
Вообще эта ошибка всегда означает, что какой-то сторонний класс не может быть загружен через Dependency Injection фреймворка Laravel, но в данном случае, это должен был обеспечить Passport. По невыясненным причинам, Passport этого не сделал.
Основные ответы на просторах интернета были в духе "добавь в composer.json laravel/passport 3.3.3 и запусти composer update", но этот вариант не сработал (Естественно, даже с более новыми версиями).
Решение
Как вариант, подключить собственный сервис провайдер.
Создаем файл App/Providers/JwtServiceProvider.php со следующим содержимым:
<?php declare(strict_types=1);
namespace App\Ship\Providers;
use Illuminate\Support\ServiceProvider;
use Lcobucci\JWT\Configuration;
/**
* Подключаем Lcobucci\JWT вручную т.к. через Passport не работает
*/
class JwtServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(Configuration::class, function ($app) {
return Configuration::forSymmetricSigner(
new \Lcobucci\JWT\Signer\Hmac\Sha256(), // Алгоритм подписания
\Lcobucci\JWT\Signer\Key\InMemory::plainText(env('PASSPORT_CLIENT_SECRET')) // Ключ для работы
);
});
}
public function boot()
{
//
}
}
В env('PASSPORT_CLIENT_SECRET') - должен быть секретный ключ, который был сгенерирован при запуске php artisan passport:keys
.
Регистрируем сервис провайдер в config/app.php
(Если laravel до 11 версии) или в bootstrap/providers.php
(если Laravel 11)
Использовать можно следующим образом:
<?php
namespace App\Containers\Authentication\Actions;
use App\Containers\Authentication\UI\API\Requests\LogoutRequest;
use Lcobucci\JWT\Configuration;
use Lorisleiva\Actions\Concerns\AsAction;
class LogoutAction
{
use AsAction;
public function __construct(
private readonly Configuration $jwtConfig,
)
{
}
public function handle()
{
// ...
}
public function asController(LogoutRequest $request)
{
//...
$id = $this->jwtConfig->parser()->parse($request->bearerToken())->claims()->get('jti');
//...
}
}
Таким образом, парсер jwt Будет работать, как и остальные сервисы Lcobucci.