-
-
Notifications
You must be signed in to change notification settings - Fork 614
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
set_cookies
option to store JWT in secure cookies
- Loading branch information
Showing
11 changed files
with
228 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?xml version="1.0" ?> | ||
|
||
<container xmlns="http://symfony.com/schema/dic/services" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> | ||
|
||
<services> | ||
<service id="lexik_jwt_authentication.cookie_provider" class="Lexik\Bundle\JWTAuthenticationBundle\Security\Http\Cookie\JWTCookieProvider" abstract="true"> | ||
<argument>null</argument> <!-- Default name --> | ||
<argument>null</argument> <!-- Default lifetime --> | ||
<argument/> <!-- Default samesite --> | ||
<argument/> <!-- Default path --> | ||
<argument>null</argument> <!-- Default domain --> | ||
</service> | ||
</services> | ||
</container> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
use Lexik\Bundle\JWTAuthenticationBundle\Event\AuthenticationSuccessEvent; | ||
use Lexik\Bundle\JWTAuthenticationBundle\Events; | ||
use Lexik\Bundle\JWTAuthenticationBundle\Response\JWTAuthenticationSuccessResponse; | ||
use Lexik\Bundle\JWTAuthenticationBundle\Security\Http\Cookie\JWTCookieProvider; | ||
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface; | ||
use Symfony\Component\EventDispatcher\EventDispatcherInterface; | ||
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface as ContractsEventDispatcherInterface; | ||
|
@@ -17,16 +18,25 @@ | |
* AuthenticationSuccessHandler. | ||
* | ||
* @author Dev Lexik <[email protected]> | ||
* @author Robin Chalas <[email protected]> | ||
* | ||
* @final | ||
*/ | ||
class AuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface | ||
{ | ||
private $cookieProviders; | ||
|
||
protected $jwtManager; | ||
protected $dispatcher; | ||
|
||
public function __construct(JWTTokenManagerInterface $jwtManager, EventDispatcherInterface $dispatcher) | ||
/** | ||
* @param iterable|JWTCookieProvider[] $cookieProviders | ||
*/ | ||
public function __construct(JWTTokenManagerInterface $jwtManager, EventDispatcherInterface $dispatcher, $cookieProviders = []) | ||
{ | ||
$this->jwtManager = $jwtManager; | ||
$this->dispatcher = $dispatcher; | ||
$this->cookieProviders = $cookieProviders; | ||
} | ||
|
||
/** | ||
|
@@ -43,7 +53,12 @@ public function handleAuthenticationSuccess(UserInterface $user, $jwt = null) | |
$jwt = $this->jwtManager->create($user); | ||
} | ||
|
||
$response = new JWTAuthenticationSuccessResponse($jwt); | ||
$jwtCookies = []; | ||
foreach ($this->cookieProviders as $cookieProvider) { | ||
$jwtCookies[] = $cookieProvider->createCookie($jwt); | ||
} | ||
|
||
$response = new JWTAuthenticationSuccessResponse($jwt, [], $jwtCookies); | ||
$event = new AuthenticationSuccessEvent(['token' => $jwt], $user, $response); | ||
|
||
if ($this->dispatcher instanceof ContractsEventDispatcherInterface) { | ||
|
@@ -52,7 +67,17 @@ public function handleAuthenticationSuccess(UserInterface $user, $jwt = null) | |
$this->dispatcher->dispatch(Events::AUTHENTICATION_SUCCESS, $event); | ||
} | ||
|
||
$response->setData($event->getData()); | ||
$responseData = $event->getData(); | ||
|
||
if ($jwtCookies) { | ||
unset($responseData['token']); | ||
} | ||
|
||
if ($responseData) { | ||
$response->setData($responseData); | ||
} else { | ||
$response->setStatusCode(JWTAuthenticationSuccessResponse::HTTP_NO_CONTENT); | ||
} | ||
|
||
return $response; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
<?php | ||
|
||
namespace Lexik\Bundle\JWTAuthenticationBundle\Security\Http\Cookie; | ||
|
||
use Symfony\Component\HttpFoundation\Cookie; | ||
|
||
/** | ||
* Creates secure JWT cookies. | ||
*/ | ||
final class JWTCookieProvider | ||
{ | ||
private $defaultName; | ||
private $defaultLifetime; | ||
private $defaultSameSite; | ||
private $defaultPath; | ||
private $defaultDomain; | ||
|
||
/** | ||
* @param string|null $defaultName | ||
* @param int|null $defaultLifetime | ||
* @param string $defaultPath | ||
* @param string|null $defaultDomain | ||
* @param string $defaultSameSite | ||
*/ | ||
public function __construct($defaultName = null, $defaultLifetime = 0, $defaultSameSite = Cookie::SAMESITE_LAX, $defaultPath = '/', $defaultDomain = null) | ||
{ | ||
$this->defaultName = $defaultName; | ||
$this->defaultLifetime = $defaultLifetime; | ||
$this->defaultSameSite = $defaultSameSite; | ||
$this->defaultPath = $defaultPath; | ||
$this->defaultDomain = $defaultDomain; | ||
} | ||
|
||
/** | ||
* Creates a secure cookie containing the passed JWT. | ||
* | ||
* For each argument (all args except $jwt), if it is omitted or set to null then the | ||
* default value defined via the constructor will be used. | ||
* | ||
* @param string $jwt | ||
* @param string|null $name | ||
* @param int|string|\DateTimeInterface|null $expiresAt | ||
* @param string|null $sameSite | ||
* @param string|null $path | ||
* @param string|null $domain | ||
* | ||
* @return Cookie | ||
*/ | ||
public function createCookie($jwt, $name = null, $expiresAt = null, $sameSite = null, $path = null, $domain = null) | ||
{ | ||
if (!$name && !$this->defaultName) { | ||
throw new \LogicException(sprintf('The cookie name must be provided, either pass it as 2nd argument of %s or set a default name via the constructor.', __METHOD__)); | ||
} | ||
|
||
if (!$expiresAt && !$this->defaultLifetime) { | ||
throw new \LogicException(sprintf('The cookie expiration time must be provided, either pass it as 3rd argument of %s or set a default lifetime via the constructor.', __METHOD__)); | ||
} | ||
|
||
return new Cookie( | ||
$name ?: $this->defaultName, | ||
$jwt, | ||
null === $expiresAt ? (time() + $this->defaultLifetime) : $expiresAt, | ||
$path ?: $this->defaultPath, | ||
$domain ?: $this->defaultDomain, | ||
true, | ||
true, | ||
false, | ||
$sameSite ?: $this->defaultSameSite | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.