Как реализовать refre sh JWT токен в symfony - PullRequest
0 голосов
/ 15 апреля 2020

Я использую https://github.com/lexik/LexikJWTAuthenticationBundle и https://github.com/markitosgv/JWTRefreshTokenBundle Но я понятия не имею, как реализовать токен auto refre sh, если срок его действия истек, и не просить пользователя заполнить форму входа еще раз, я хочу сделать это на стороне сервера автоматически. После входа в систему пользователь получает refre sh токен, и этот токен можно использовать только один раз. Как добавить токен jwt в заголовки:

<?php    
namespace App\EventListener;
use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent;
use Symfony\Component\HttpFoundation\Cookie;

class AuthSuccessListener{

    private $secure = false;
    private $tokenTtl;

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

    public function onAuthSuccess(AuthenticationSuccessEvent $event){
        $response = $event->getResponse();
        $data = $event->getData();
        $token = $data['token'];
        unset($data['token']);
        unset($data['refresh_token']);
        $event->setData($data);
        $response->headers->setCookie(
            new Cookie( 'BEARER', $token, (new \DateTime())->add(new \DateInterval('PT'. $this->tokenTtl . 'S')), '/', null, $this->secure)
        );
    }
}


<?php       
namespace App\EventListener;       
use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Cookie;

class RefreshTokenListener implements EventSubscriberInterface
{

    private $ttl;

    private $cookieSecure = false;

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

    public function setRefreshToken(AuthenticationSuccessEvent $event)
    {
        $refreshToken = $event->getData()['refresh_token'];
        $response = $event->getResponse();

        if ($refreshToken) {
            $response->headers->setCookie(new Cookie('REFRESH_TOKEN', $refreshToken, (
            new \DateTime())
                ->add(new \DateInterval('PT' . $this->ttl . 'S')), '/', null, $this->cookieSecure));
        }
    }

    public static function getSubscribedEvents()
    {
        return [
            'lexik_jwt_authentication.on_authentication_success' => [
                ['setRefreshToken']
            ]
        ];
    }
}

<?php       
namespace App\EventListener;      
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class RequestListener implements EventSubscriberInterface
{
    public function onKernelRequest(RequestEvent $event)
    {
        $request = $event->getRequest();

        $request->attributes->set('refresh_token', $request->cookies->get('REFRESH_TOKEN'));
    }

    public static function getSubscribedEvents()
    {
        return [
            KernelEvents::REQUEST => [
                ['onKernelRequest']
            ]
        ];
    }
}

И конфиги jwt yaml

lexik_jwt_authentication:
    secret_key: '%env(resolve:JWT_SECRET_KEY)%'
    public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
    pass_phrase: '%env(JWT_PASSPHRASE)%'
    token_ttl: 7
    token_extractors:
        authorization_header:
            enabled: false
            prefix: Bearer
            name: Authorization
        cookie:
            enabled: true
            name: BEARER

gesdinet_jwt_refresh_token:
  ttl: 2592000
  single_use: true
  firewall: api

И Услуги

App\EventListener\AuthSuccessListener:
    arguments: ['%lexik_jwt_authentication.token_ttl%']
    tags:
        - { name: kernel.event_listener, event: lexik_jwt_authentication.on_authentication_success, method: onAuthSuccess, priority: -2 }

App\EventListener\RefreshTokenListener:
    arguments: ['%gesdinet_jwt_refresh_token.ttl%']
...