Files
Lesstime/src/Security/ApiTokenAuthenticator.php
T

67 lines
2.3 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Security;
use App\Module\Core\Domain\Entity\User;
use App\Module\Core\Infrastructure\Doctrine\DoctrineUserRepository;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
class ApiTokenAuthenticator extends AbstractAuthenticator
{
public function __construct(
private readonly DoctrineUserRepository $userRepository,
) {}
public function supports(Request $request): ?bool
{
return $request->headers->has('Authorization')
&& str_starts_with((string) $request->headers->get('Authorization'), 'Bearer ');
}
public function authenticate(Request $request): Passport
{
$authHeader = (string) $request->headers->get('Authorization');
$token = substr($authHeader, 7);
if ('' === $token) {
throw new CustomUserMessageAuthenticationException('API token missing.');
}
return new SelfValidatingPassport(
new UserBadge($token, function (string $token): ?User {
$user = $this->userRepository->findOneBy(['apiToken' => $token]);
if (null === $user) {
throw new CustomUserMessageAuthenticationException('Invalid API token.');
}
return $user;
})
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
return null;
}
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
{
return new JsonResponse(
['error' => $exception->getMessageKey()],
Response::HTTP_UNAUTHORIZED
);
}
}