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

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