82 lines
3.5 KiB
PHP
82 lines
3.5 KiB
PHP
<?php
|
|
|
|
namespace Lexik\Bundle\JWTAuthenticationBundle\Security\Http\Cookie;
|
|
|
|
use Lexik\Bundle\JWTAuthenticationBundle\Helper\JWTSplitter;
|
|
use Symfony\Component\HttpFoundation\Cookie;
|
|
use Symfony\Component\HttpKernel\Kernel;
|
|
|
|
/**
|
|
* Creates secure JWT cookies.
|
|
*/
|
|
final class JWTCookieProvider
|
|
{
|
|
private ?string $defaultName;
|
|
private ?int $defaultLifetime;
|
|
private ?string $defaultSameSite;
|
|
private ?string $defaultPath;
|
|
private ?string $defaultDomain;
|
|
private bool $defaultSecure;
|
|
private bool $defaultHttpOnly;
|
|
private array $defaultSplit;
|
|
private bool $defaultPartitioned;
|
|
|
|
public function __construct(?string $defaultName = null, ?int $defaultLifetime = 0, ?string $defaultSameSite = Cookie::SAMESITE_LAX, ?string $defaultPath = '/', ?string $defaultDomain = null, bool $defaultSecure = true, bool $defaultHttpOnly = true, array $defaultSplit = [], bool $defaultPartitioned = false)
|
|
{
|
|
$this->defaultName = $defaultName;
|
|
$this->defaultLifetime = $defaultLifetime;
|
|
$this->defaultSameSite = $defaultSameSite;
|
|
$this->defaultPath = $defaultPath;
|
|
$this->defaultDomain = $defaultDomain;
|
|
$this->defaultSecure = $defaultSecure;
|
|
$this->defaultHttpOnly = $defaultHttpOnly;
|
|
$this->defaultSplit = $defaultSplit;
|
|
$this->defaultPartitioned = $defaultPartitioned;
|
|
|
|
if ($defaultPartitioned && Kernel::VERSION < '6.4') {
|
|
throw new \LogicException(sprintf('The `partitioned` option for cookies is only available for Symfony 6.4 and above. You are currently on version %s', Kernel::VERSION));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates a secure cookie containing the passed JWT.
|
|
*
|
|
* For each argument (all args except $jwt), if omitted or set to null then the
|
|
* default value defined via the constructor will be used.
|
|
*/
|
|
public function createCookie(string $jwt, ?string $name = null, $expiresAt = null, ?string $sameSite = null, ?string $path = null, ?string $domain = null, ?bool $secure = null, ?bool $httpOnly = null, array $split = [], ?bool $partitioned = null): Cookie
|
|
{
|
|
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 && null === $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__));
|
|
}
|
|
|
|
if ($partitioned && Kernel::VERSION < '6.4') {
|
|
throw new \LogicException(sprintf('The `partitioned` option for cookies is only available for Symfony 6.4 and above. You are currently on version %s', Kernel::VERSION));
|
|
}
|
|
|
|
$jwtParts = new JWTSplitter($jwt);
|
|
$jwt = $jwtParts->getParts($split ?: $this->defaultSplit);
|
|
|
|
if (null === $expiresAt) {
|
|
$expiresAt = 0 === $this->defaultLifetime ? 0 : (time() + $this->defaultLifetime);
|
|
}
|
|
|
|
return Cookie::create(
|
|
$name ?: $this->defaultName,
|
|
$jwt,
|
|
$expiresAt,
|
|
$path ?: $this->defaultPath,
|
|
$domain ?: $this->defaultDomain,
|
|
$secure ?: $this->defaultSecure,
|
|
$httpOnly ?: $this->defaultHttpOnly,
|
|
false,
|
|
$sameSite ?: $this->defaultSameSite,
|
|
$partitioned ?: $this->defaultPartitioned
|
|
);
|
|
}
|
|
}
|