Allow to specify the cookie type for appframework responses

In general it is good to set them to Lax. But also to give devs more
control over them is not a bad thing.

Helps with #21474

Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
This commit is contained in:
Roeland Jago Douma 2020-06-19 09:31:47 +02:00 committed by backportbot[bot]
parent d1c19fbe23
commit c21a976bc4
5 changed files with 36 additions and 12 deletions

View File

@ -151,6 +151,8 @@ class App {
if ($value['expireDate'] instanceof \DateTime) { if ($value['expireDate'] instanceof \DateTime) {
$expireDate = $value['expireDate']->getTimestamp(); $expireDate = $value['expireDate']->getTimestamp();
} }
$sameSite = $value['sameSite'] ?? 'Lax';
$io->setCookie( $io->setCookie(
$name, $name,
$value['value'], $value['value'],
@ -158,7 +160,8 @@ class App {
$container->getServer()->getWebRoot(), $container->getServer()->getWebRoot(),
null, null,
$container->getServer()->getRequest()->getServerProtocol() === 'https', $container->getServer()->getRequest()->getServerProtocol() === 'https',
true true,
$sameSite
); );
} }

View File

@ -92,8 +92,20 @@ class Output implements IOutput {
* @param bool $secure * @param bool $secure
* @param bool $httpOnly * @param bool $httpOnly
*/ */
public function setCookie($name, $value, $expire, $path, $domain, $secure, $httpOnly) { public function setCookie($name, $value, $expire, $path, $domain, $secure, $httpOnly, $sameSite = 'Lax') {
$path = $this->webRoot ? : '/'; $path = $this->webRoot ? : '/';
setcookie($name, $value, $expire, $path, $domain, $secure, $httpOnly);
if (PHP_VERSION_ID < 70300) {
setcookie($name, $value, $expire, $path, $domain, $secure, $httpOnly);
} else {
setcookie($name, $value, [
'expires' => $expire,
'path' => $path,
'domain' => $domain,
'secure' => $secure,
'httponly' => $httpOnly,
'samesite' => $sameSite
]);
}
} }
} }

View File

@ -72,7 +72,8 @@ interface IOutput {
* @param string $domain * @param string $domain
* @param bool $secure * @param bool $secure
* @param bool $httpOnly * @param bool $httpOnly
* @param string $sameSite (added in 20)
* @since 8.1.0 * @since 8.1.0
*/ */
public function setCookie($name, $value, $expire, $path, $domain, $secure, $httpOnly); public function setCookie($name, $value, $expire, $path, $domain, $secure, $httpOnly, $sameSite = 'Lax');
} }

View File

@ -133,11 +133,12 @@ class Response {
* @param \DateTime|null $expireDate Date on that the cookie should expire, if set * @param \DateTime|null $expireDate Date on that the cookie should expire, if set
* to null cookie will be considered as session * to null cookie will be considered as session
* cookie. * cookie.
* @param string $sameSite The samesite value of the cookie. Defaults to Lax. Other possibilities are Strict or None
* @return $this * @return $this
* @since 8.0.0 * @since 8.0.0
*/ */
public function addCookie($name, $value, \DateTime $expireDate = null) { public function addCookie($name, $value, \DateTime $expireDate = null, $sameSite = 'Lax') {
$this->cookies[$name] = ['value' => $value, 'expireDate' => $expireDate]; $this->cookies[$name] = ['value' => $value, 'expireDate' => $expireDate, 'sameSite' => $sameSite];
return $this; return $this;
} }

View File

@ -108,10 +108,12 @@ class ResponseTest extends \Test\TestCase {
'foo' => [ 'foo' => [
'value' => 'bar', 'value' => 'bar',
'expireDate' => null, 'expireDate' => null,
'sameSite' => 'Lax',
], ],
'bar' => [ 'bar' => [
'value' => 'foo', 'value' => 'foo',
'expireDate' => new \DateTime('1970-01-01') 'expireDate' => new \DateTime('1970-01-01'),
'sameSite' => 'Lax',
] ]
]; ];
$this->assertEquals($expectedResponse, $this->childResponse->getCookies()); $this->assertEquals($expectedResponse, $this->childResponse->getCookies());
@ -143,7 +145,8 @@ class ResponseTest extends \Test\TestCase {
$expected = [ $expected = [
'foo' => [ 'foo' => [
'value' => 'expired', 'value' => 'expired',
'expireDate' => new \DateTime('1971-01-01') 'expireDate' => new \DateTime('1971-01-01'),
'sameSite' => 'Lax',
] ]
]; ];
@ -159,11 +162,13 @@ class ResponseTest extends \Test\TestCase {
$expected = [ $expected = [
'foo' => [ 'foo' => [
'value' => 'bar', 'value' => 'bar',
'expireDate' => null 'expireDate' => null,
'sameSite' => 'Lax',
], ],
'bar' => [ 'bar' => [
'value' => 'foo', 'value' => 'foo',
'expireDate' => null 'expireDate' => null,
'sameSite' => 'Lax',
] ]
]; ];
$cookies = $this->childResponse->getCookies(); $cookies = $this->childResponse->getCookies();
@ -173,11 +178,13 @@ class ResponseTest extends \Test\TestCase {
$expected = [ $expected = [
'foo' => [ 'foo' => [
'value' => 'expired', 'value' => 'expired',
'expireDate' => new \DateTime('1971-01-01') 'expireDate' => new \DateTime('1971-01-01'),
'sameSite' => 'Lax',
], ],
'bar' => [ 'bar' => [
'value' => 'expired', 'value' => 'expired',
'expireDate' => new \DateTime('1971-01-01') 'expireDate' => new \DateTime('1971-01-01'),
'sameSite' => 'Lax',
] ]
]; ];