Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Impossible to set a Session Cookie for jwt_s #809

Closed
victormhg opened this issue Dec 1, 2020 · 3 comments
Closed

Impossible to set a Session Cookie for jwt_s #809

victormhg opened this issue Dec 1, 2020 · 3 comments

Comments

@victormhg
Copy link

victormhg commented Dec 1, 2020

Hi,

I'm trying to set the configuration in "lexik_jwt_authentication.yaml" to follow the guidelines of the article Getting Token Authentication Right in a Stateless Single Page Application (that is mentioned in the docs of this bundle) to automatically generating split cookies.

According the article, we need two cookies, one (named jwt_hp) for the header and payload parts of the JWT, with a defined lifetime of 30 minutes and a second (named jwt_s) for the signature part of the JWT, as a Session Cookie.

In order to create a Session Cookie, we need to set the lifetime to 0, but this is impossible, because the lifetime is defaulted to the token_ttl lifetime or, if token_ttl is set to 0, we get the error "The cookie expiration time must be provided, either pass it as 3rd argument of Lexik\Bundle\JWTAuthenticationBundle\Security\Http\Cookie\JWTCookieProvider::createCookie or set a default lifetime via the constructor."

How can we create the jwt_s cookie as a Session Cookie?

@chalasr
Copy link
Collaborator

chalasr commented Sep 16, 2021

I think we need a new, dedicated option here.

@remoteclient
Copy link

Hi,

In the document there is no mention of a refresh cookie and the cookie lifetime is extended with every authenticated request:

  • Keeping them authenticated between requests

Therefore I wrote a subscriber to do it:

<?php
/**
 * Class JWTRefreshCookieSubscriber
 * @package MWS\UserBundle\EventSubscriber
 * @author Martin Walther <martin@myweb.solutions>
 *
 * (c) MyWebSolutions
 */

namespace MWS\UserBundle\EventSubscriber;

use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTAuthenticatedEvent;
use Lexik\Bundle\JWTAuthenticationBundle\Events;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTManager;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\User\UserInterface;

class JWTRefreshCookieSubscriber implements EventSubscriberInterface
{
    /**
     * @var array
     */
    private array $payload = [];

    /**
     * @var UserInterface
     */
    private UserInterface $user;

    /**
     * @var JWTManager
     */
    private JWTManager $jwtManager;

    /**
     * @var array
     */
    private array $cookieProviders;

    /**
     * @param JWTManager $jwtManager
     * @param array $cookieProviders
     */
    public function __construct(JWTManager $jwtManager, array $cookieProviders = [])
    {
        $this->jwtManager = $jwtManager;
        $this->cookieProviders = $cookieProviders;
    }

    public static function getSubscribedEvents(): array
    {
        return [
            Events::JWT_AUTHENTICATED => 'onAuthenticatedAccess',
            KernelEvents::RESPONSE => 'onAuthenticatedResponse'
        ];
    }

    public function onAuthenticatedAccess(JWTAuthenticatedEvent $event)
    {
        $this->payload = $event->getPayload();
        $this->user = $event->getToken()->getUser();
    }

    public function onAuthenticatedResponse(ResponseEvent $event)
    {
        if ($this->payload && $this->user) {
            $jwt = $this->jwtManager->create($this->user);
            $response = $event->getResponse();
            foreach ($this->cookieProviders as $cookieProvider) {
                $response->headers->setCookie($cookieProvider->createCookie($jwt));
            }
        }
    }
}

So what is left are two things:

  1. allow to have the session cookie a lifetime of 0 seconds
  2. a "2FA" role is needed to indicate that the authentication process is not complete and the client has to provide a second factor.

For the 2. part.... should I open a new issue for that?

@JeremyPasco
Copy link
Contributor

Hi, I juste made a pull request for the session cookie problem here #958

@chalasr chalasr closed this as completed Apr 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants