src/Security/ApiKeyAuthenticator.php line 18

Open in your IDE?
  1. <?php
  2. namespace App\Security;
  3. use App\Entity\ApiToken;
  4. use Doctrine\ORM\EntityManagerInterface;
  5. use Symfony\Component\HttpFoundation\JsonResponse;
  6. use Symfony\Component\HttpFoundation\Request;
  7. use Symfony\Component\HttpFoundation\Response;
  8. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  9. use Symfony\Component\Security\Core\Exception\AuthenticationException;
  10. use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
  11. use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator;
  12. use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
  13. use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
  14. use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
  15. class ApiKeyAuthenticator extends AbstractAuthenticator
  16. {
  17.     protected $_em;
  18.     public function __construct(EntityManagerInterface $em)
  19.     {
  20.         $this->_em $em;
  21.     }
  22.     public function supports(Request $request): ?bool
  23.     {
  24.         return $request->headers->has('Authorization') && str_starts_with($request->headers->get('Authorization'), 'Bearer');
  25.     }
  26.     public function authenticate(Request $request): Passport
  27.     {
  28.         $authorizationHeader $request->headers->get('Authorization');
  29.         if (null === $authorizationHeader) {
  30.             // The token header was empty, authentication fails with HTTP Status
  31.             // Code 401 "Unauthorized"
  32.             throw new CustomUserMessageAuthenticationException('No API token provided');
  33.         }
  34.         $apiToken substr($authorizationHeader7);
  35.         return new SelfValidatingPassport(new UserBadge($apiToken, function ($userIdentifier) {
  36.             $token $this->_em->getRepository(ApiToken::class)->findOneBy([
  37.                 'token' => $userIdentifier,
  38.             ]);
  39.             if (!$token) {
  40.                 throw new CustomUserMessageAuthenticationException(
  41.                     'Invalid API Token'
  42.                 );
  43.             }
  44.             if ($token->isExpired()) {
  45.                 throw new CustomUserMessageAuthenticationException(
  46.                     'Token expired'
  47.                 );
  48.             }
  49.             return $token->getUser();
  50.         }));
  51.     }
  52.     public function onAuthenticationSuccess(Request $requestTokenInterface $token$providerKey): ?Response
  53.     {
  54.         return null;
  55.     }
  56.     public function onAuthenticationFailure(Request $requestAuthenticationException $exception): ?Response
  57.     {
  58.         $data = [
  59.             // you may want to customize or obfuscate the message first
  60.             'message' => strtr($exception->getMessageKey(), $exception->getMessageData())
  61.             // or to translate this message
  62.             // $this->translator->trans($exception->getMessageKey(), $exception->getMessageData())
  63.         ];
  64.         return new JsonResponse($dataResponse::HTTP_UNAUTHORIZED);
  65.     }
  66. }