Skip to content

Instantly share code, notes, and snippets.

@benjaminrau
Last active May 19, 2021 19:57
Show Gist options
  • Select an option

  • Save benjaminrau/865f94d142605eb72a23a34ccdd0617a to your computer and use it in GitHub Desktop.

Select an option

Save benjaminrau/865f94d142605eb72a23a34ccdd0617a to your computer and use it in GitHub Desktop.

Revisions

  1. Benjamin Rau revised this gist Jan 22, 2020. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion JWTDecodedEventListener.php
    Original file line number Diff line number Diff line change
    @@ -47,7 +47,7 @@ public function onJWTDecoded(JWTDecodedEvent $event)
    if (
    $user &&
    $user->getTokenValidAfter() instanceof \DateTime &&
    $payload[JWTCreatedEventListener::PAYLOAD_KEY_FOR_JWT_CREATION_TIMESTAMP] < $user->getTokenValidAfter()->getTimestamp()
    $payload['iat'] < $user->getTokenValidAfter()->getTimestamp()
    ) {
    $event->markAsInvalid();
    }
  2. Benjamin Rau created this gist Jan 22, 2020.
    48 changes: 48 additions & 0 deletions InvalidateTokenEventListener.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,48 @@
    <?php

    namespace Emma\UserBundle\EventListener;

    use Doctrine\ORM\EntityManagerInterface;
    use Emma\UserBundle\Entity\User;
    use FOS\UserBundle\Event\FormEvent;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    use FOS\UserBundle\FOSUserEvents;
    use Symfony\Component\HttpFoundation\JsonResponse;
    use Symfony\Component\HttpFoundation\Response;

    class InvalidateTokenEventListener implements EventSubscriberInterface {

    /**
    * @var EntityManagerInterface
    */
    private $entityManager;

    public function __construct(EntityManagerInterface $entityManager)
    {
    $this->entityManager = $entityManager;
    }

    /**
    * @return array
    */
    public static function getSubscribedEvents()
    {
    return array(
    FOSUserEvents::RESETTING_RESET_SUCCESS => 'invalidateToken',
    FOSUserEvents::CHANGE_PASSWORD_SUCCESS => 'invalidateToken',
    );
    }

    /**
    * @param FormEvent $event
    */
    public function invalidateToken(FormEvent $event)
    {
    /** @var User $user */
    $user = $event->getForm()->getData();

    $user->setTokenValidAfter(new \DateTime());
    $this->entityManager->persist($user);
    $this->entityManager->flush();
    }
    }
    55 changes: 55 additions & 0 deletions JWTDecodedEventListener.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,55 @@
    <?php

    namespace Emma\AppBundle\EventListener;

    use Doctrine\ORM\EntityManagerInterface;
    use Emma\UserBundle\Entity\User;
    use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTDecodedEvent;

    class JWTDecodedEventListener
    {
    /**
    * @var EntityManagerInterface
    */
    private $entityManager;

    /**
    * @param EntityManagerInterface $entityManager
    */
    public function __construct(EntityManagerInterface $entityManager)
    {
    $this->entityManager = $entityManager;
    }

    /**
    * @param JWTDecodedEvent $event
    *
    * @throws \Exception
    *
    * @return void
    */
    public function onJWTDecoded(JWTDecodedEvent $event)
    {
    $payload = $event->getPayload();

    /**
    * As a mechanism to invalidate issued tokes we force token issue date to be higher than a date stored on User::tokenValidAfter
    * By updating the User::tokenValidAfter to current date all previously issued tokens become invalid
    *
    * Its intended we dont mark as invalid if user isnt found on persistence level because we rely on core JWT
    * implementation to handle this case. We want to handle only the validation of tokenValidAfter here.
    *
    * @var $user User
    */
    $user = $this->entityManager->getRepository(User::class)->findOneBy([
    'username' => $payload[JWTCreatedEventListener::PAYLOAD_KEY_FOR_USERNAME]
    ]);
    if (
    $user &&
    $user->getTokenValidAfter() instanceof \DateTime &&
    $payload[JWTCreatedEventListener::PAYLOAD_KEY_FOR_JWT_CREATION_TIMESTAMP] < $user->getTokenValidAfter()->getTimestamp()
    ) {
    $event->markAsInvalid();
    }
    }
    }