Привет ребят.
Есть аутентификатор для
api запросов, который отрабатывает корректно ( юзер из секьюрити формируется ) при
CUrl запросах вида:
curl --location --request GET 'http://localhost:8081/api/v1/account/userinfo' \
--header 'Authorization: Bearer %api_token%'
Но в тесте вместо
User-а в методе
AccountController::getUser прилетает
null:
Тест:
class UserinfoTest extends DbWebTestCase
{
protected EntityManagerInterface $em;
protected KernelBrowser $client;
private const API_PREFIX = '/api/v1';
protected function setUp(): void
{
$this->client = static::createClient();
$this->client->disableReboot();
$kernel = self::bootKernel();
DatabasePrimer::prime($kernel);
$this->em = $kernel->getContainer()->get('doctrine')->getManager();
}
public function test_userinfo_success()
{
$userRepository = $this->em->getRepository(User::class);
$testUser = $userRepository->findOneBy(['phone' => '+7 (000) 000-00-01']);
$token = $testUser->getTokens()[0]->getToken();
$this->client->request('GET', self::API_PREFIX . '/account/userinfo', [
'headers' => [
'Authorization' => 'Bearer ' . $token,
],
]);
...
}
}
Конфигурация:
security:
enable_authenticator_manager: true
password_hashers:
App\Model\User\Entity\User\User:
algorithm: 'auto'
providers:
app_user_provider:
entity:
class: App\Model\User\Entity\User\User
property: id
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
lazy: true
provider: app_user_provider
custom_authenticators:
- App\Security\Authenticator\ApiTokenAuthenticator
access_control:
Аутентификатор:
class ApiTokenAuthenticator extends AbstractAuthenticator
{
public function __construct(
private ApiTokenRepository $repository
)
{
}
public function supports(Request $request): ?bool
{
$authHeader = $request->headers->get('Authorization');
return $authHeader && str_starts_with($authHeader, 'Bearer ');
}
public function authenticate(Request $request): PassportInterface
{
$authHeader = $request->headers->get('Authorization');
$token = substr($authHeader, 7);
$apiToken = $this->repository->findOneBy(['token' => $token]) ??
throw new CustomUserMessageAuthenticationException('Invalid API Token');
if ($apiToken->isExpired()) {
throw new CustomUserMessageAuthenticationException('Token expired');
}
$user = $apiToken->getUser();
return new Passport(
new UserBadge($user->getId()),
new CustomCredentials(
fn($credentials, UserInterface $user) => !$credentials->isExpired(),
$apiToken
)
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
return null;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
{
return new JsonResponse([
'message' => $exception->getMessageKey()
], Response::HTTP_UNAUTHORIZED);
}
}
Контроллер:
#[Route('api/v1/account')]
class AccountController extends AbstractController
{
public function __construct(
private LoggerInterface $logger
)
{
}
protected function getUser(): User
{
return parent::getUser();
}
#[Route('/userinfo')]
public function userInfo(): JsonResponse
{
// dump('СЮДА попадаю почему то при тестировании, хотя аутентификатор не должен пускать');
// *** При курле все норм ***
// !!! При запуске теста поломка, возвращается null вместо User !!!
$user = $this->getUser();
$this->logger->warning(json_encode($user));
return $this->json([
'code' => 200,
'data' => [
'user' => [
'username' => (string)$user->getUsername(),
'email' => (string)$user->getEmail(),
'phone' => (string)$user->getPhone(),
]
]
], 200, []);
}
}
Мне бы хотелось, чтобы при прилетании заголовка:
Authorization: Bearer ...
Аутентификатор всегда бы отрабатывал