JWTRefreshTokenBundle icon indicating copy to clipboard operation
JWTRefreshTokenBundle copied to clipboard

Installation in SF 6.1 with Apiplatform

Open MakFly opened this issue 1 year ago • 1 comments

Hello guys !, I encountered a lot of problems when installing version 1.1 under SF6 and apiplatform. I allow myself to make a thread to explain the process for the proper functioning of the package.

Start : composer require gesdinet/jwt-refresh-token-bundle

Files : Security.yaml Add between login and api =>

refresh:
         pattern: ^/api/token/refresh
         stateless: true
         provider: user_provider_service_id
          refresh_jwt: ~

line "access_control" - { path: ^/api/login_check|token/refresh, roles: PUBLIC_ACCESS }


Files : gesdinet_jwt_refresh_token.yaml Add this line =>

gesdinet_jwt_refresh_token:
              refresh_token_class: App\Entity\RefreshToken

Make a "php bin/console c:c"

Make a "php bin/console make:migration" EDIT : "If you have nothing happens despite the launch of this command it is normal" => Make this command : symfony console doctrine:schema:update --force You should have an update that does this with the following information: "A request has just been added" INFO : I don't know if it matters but I created an Id getter in the RefreshToken entity =>

#[ORM\Entity]
#[ORM\Table(name: 'refresh_token')]
class RefreshToken extends BaseRefreshToken
{
    public function getId() 
    {
        return $this->id;
    }
}

After all these adventures please launch your POST command on /api/login or /api/login_check or any other URI /api/login
and you should see the refresh_token in the response.json

At this issue we arrive at the fact that everything works and that the username is filled in as "email" for example according to your configuration. If you want to change the value of the "username" field of the refresh_token table. I had to update this field directly in a JWTAuthenticationSucess subscriber.

CODE :

<?php

namespace App\EventSubscriber;

use Doctrine\ORM\EntityManagerInterface;
use Gesdinet\JWTRefreshTokenBundle\Model\RefreshTokenManagerInterface;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\User\UserInterface;

class JwtAuthenticationSuccessListenerSubscriber implements EventSubscriberInterface
{
    public function __construct(private JWTTokenManagerInterface $jwtManager, RefreshTokenManagerInterface $refreshTokenManagerInterface, EntityManagerInterface $em)
    {
        $this->jwtManager = $jwtManager;
        $this->refreshTokenManagerInterface = $refreshTokenManagerInterface;
        $this->em = $em;
    }

    public function onLexikJwtAuthenticationOnAuthenticationSuccess($event): void
    {
        $data = $event->getData();
        $user = $event->getUser();
        $payload = $this->jwtManager->parse($data['token']);
        $data['data'] = [
            'payload' => $payload,
        ];
        
        if ($user instanceof UserInterface) {
            $id = $user->getId();
            if ($this->refreshTokenManagerInterface->get($data['refresh_token'])) {
                $repo = $this->em->getRepository($this->refreshTokenManagerInterface->getClass());
                $newEntrie = $repo->find($this->refreshTokenManagerInterface->get($data['refresh_token']));
                $newEntrie->setUsername($id);
                $this->em->flush();
            }
        }
        $event->setData($data);
    }

    public static function getSubscribedEvents(): array
    {
        return [
            'lexik_jwt_authentication.on_authentication_success' => 'onLexikJwtAuthenticationOnAuthenticationSuccess',
        ];
    }
}

IF you have many questions ;) comments this post.

Best regards

MakFly avatar Jul 08 '22 09:07 MakFly

or a different access_control:

- { path: ^/api/login, roles: PUBLIC_ACCESS }
- { path: ^/api/token/refresh, roles: PUBLIC_ACCESS }

simplyniceweb avatar Oct 23 '22 19:10 simplyniceweb