vendor/lexik/jwt-authentication-bundle/Services/JWTManager.php line 138

Open in your IDE?
  1. <?php
  2. namespace Lexik\Bundle\JWTAuthenticationBundle\Services;
  3. use Lexik\Bundle\JWTAuthenticationBundle\Encoder\HeaderAwareJWTEncoderInterface;
  4. use Lexik\Bundle\JWTAuthenticationBundle\Encoder\JWTEncoderInterface;
  5. use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTCreatedEvent;
  6. use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTDecodedEvent;
  7. use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTEncodedEvent;
  8. use Lexik\Bundle\JWTAuthenticationBundle\Events;
  9. use Lexik\Bundle\JWTAuthenticationBundle\Exception\JWTDecodeFailureException;
  10. use Lexik\Bundle\JWTAuthenticationBundle\Services\PayloadEnrichment\NullEnrichment;
  11. use Symfony\Component\PropertyAccess\PropertyAccess;
  12. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  13. use Symfony\Component\Security\Core\User\InMemoryUser;
  14. use Symfony\Component\Security\Core\User\UserInterface;
  15. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  16. /**
  17.  * Provides convenient methods to manage JWT creation/verification.
  18.  *
  19.  * @author Nicolas Cabot <n.cabot@lexik.fr>
  20.  * @author Robin Chalas <robin.chalas@gmail.com>
  21.  */
  22. class JWTManager implements JWTManagerInterfaceJWTTokenManagerInterface
  23. {
  24.     /**
  25.      * @var JWTEncoderInterface
  26.      */
  27.     protected $jwtEncoder;
  28.     /**
  29.      * @var EventDispatcherInterface
  30.      */
  31.     protected $dispatcher;
  32.     /**
  33.      * @var string
  34.      *
  35.      * @deprecated since v2.15
  36.      */
  37.     protected $userIdentityField;
  38.     /**
  39.      * @var string
  40.      */
  41.     protected $userIdClaim;
  42.     /**
  43.      * @var PayloadEnrichmentInterface
  44.     */
  45.     private $payloadEnrichment;
  46.     /**
  47.      * @param string|null $userIdClaim
  48.      */
  49.     public function __construct(JWTEncoderInterface $encoderEventDispatcherInterface $dispatcher$userIdClaim nullPayloadEnrichmentInterface $payloadEnrichment null)
  50.     {
  51.         $this->jwtEncoder $encoder;
  52.         $this->dispatcher $dispatcher;
  53.         $this->userIdentityField 'username';
  54.         $this->userIdClaim $userIdClaim;
  55.         $this->payloadEnrichment $payloadEnrichment ?? new NullEnrichment();
  56.     }
  57.     /**
  58.      * @return string The JWT token
  59.      */
  60.     public function create(UserInterface $user): string
  61.     {
  62.         $payload = ['roles' => $user->getRoles()];
  63.         $this->addUserIdentityToPayload($user$payload);
  64.         $this->payloadEnrichment->enrich($user$payload);
  65.         return $this->generateJwtStringAndDispatchEvents($user$payload);
  66.     }
  67.     /**
  68.      * @return string The JWT token
  69.      */
  70.     public function createFromPayload(UserInterface $user, array $payload): string
  71.     {
  72.         $payload array_merge(['roles' => $user->getRoles()], $payload);
  73.         $this->addUserIdentityToPayload($user$payload);
  74.         $this->payloadEnrichment->enrich($user$payload);
  75.         return $this->generateJwtStringAndDispatchEvents($user$payload);
  76.     }
  77.     /**
  78.      * @return string The JWT token
  79.      */
  80.     private function generateJwtStringAndDispatchEvents(UserInterface $user, array $payload): string
  81.     {
  82.         $jwtCreatedEvent = new JWTCreatedEvent($payload$user);
  83.         $this->dispatcher->dispatch($jwtCreatedEventEvents::JWT_CREATED);
  84.         if ($this->jwtEncoder instanceof HeaderAwareJWTEncoderInterface) {
  85.             $jwtString $this->jwtEncoder->encode($jwtCreatedEvent->getData(), $jwtCreatedEvent->getHeader());
  86.         } else {
  87.             $jwtString $this->jwtEncoder->encode($jwtCreatedEvent->getData());
  88.         }
  89.         $jwtEncodedEvent = new JWTEncodedEvent($jwtString);
  90.         $this->dispatcher->dispatch($jwtEncodedEventEvents::JWT_ENCODED);
  91.         return $jwtString;
  92.     }
  93.     /**
  94.      * {@inheritdoc}
  95.      * @throws JWTDecodeFailureException
  96.      */
  97.     public function decode(TokenInterface $token)
  98.     {
  99.         if (!($payload $this->jwtEncoder->decode($token->getCredentials()))) {
  100.             return false;
  101.         }
  102.         $event = new JWTDecodedEvent($payload);
  103.         $this->dispatcher->dispatch($eventEvents::JWT_DECODED);
  104.         if (!$event->isValid()) {
  105.             return false;
  106.         }
  107.         return $event->getPayload();
  108.     }
  109.     /**
  110.      * {@inheritdoc}
  111.      */
  112.     public function parse(string $jwtToken): array
  113.     {
  114.         $payload $this->jwtEncoder->decode($jwtToken);
  115.         $event = new JWTDecodedEvent($payload);
  116.         $this->dispatcher->dispatch($eventEvents::JWT_DECODED);
  117.         if (!$event->isValid()) {
  118.             throw new JWTDecodeFailureException(JWTDecodeFailureException::INVALID_TOKEN'The token was marked as invalid by an event listener after successful decoding.');
  119.         }
  120.         return $event->getPayload();
  121.     }
  122.     /**
  123.      * Add user identity to payload, username by default.
  124.      * Override this if you need to identify it by another property.
  125.      *
  126.      * @param array &$payload
  127.      */
  128.     protected function addUserIdentityToPayload(UserInterface $user, array &$payload)
  129.     {
  130.         $accessor PropertyAccess::createPropertyAccessor();
  131.         $identityField $this->userIdClaim ?: $this->userIdentityField;
  132.         if ($user instanceof InMemoryUser && 'username' === $identityField) {
  133.             $payload[$identityField] = $accessor->getValue($user'userIdentifier');
  134.             return;
  135.         }
  136.         $payload[$identityField] = $accessor->getValue($user$accessor->isReadable($user$identityField) ? $identityField 'user_identifier');
  137.     }
  138.     /**
  139.      * {@inheritdoc}
  140.      */
  141.     public function getUserIdentityField(): string
  142.     {
  143.         if (=== func_num_args() || func_get_arg(0)) {
  144.             trigger_deprecation('lexik/jwt-authentication-bundle''2.15''The "%s()" method is deprecated.'__METHOD__);
  145.         }
  146.         return $this->userIdentityField;
  147.     }
  148.     /**
  149.      * {@inheritdoc}
  150.      */
  151.     public function setUserIdentityField($field)
  152.     {
  153.         if (>= func_num_args() || func_get_arg(1)) {
  154.             trigger_deprecation('lexik/jwt-authentication-bundle''2.15''The "%s()" method is deprecated.'__METHOD__);
  155.         }
  156.         $this->userIdentityField $field;
  157.     }
  158.     /**
  159.      * @return string
  160.      */
  161.     public function getUserIdClaim(): ?string
  162.     {
  163.         return $this->userIdClaim;
  164.     }
  165. }