diff --git a/lib/response/sfWebResponse.class.php b/lib/response/sfWebResponse.class.php index d9bd5da5b..4ff85fd1c 100644 --- a/lib/response/sfWebResponse.class.php +++ b/lib/response/sfWebResponse.class.php @@ -162,17 +162,18 @@ public function isHeaderOnly() /** * Sets a cookie. * - * @param string $name HTTP header name - * @param string $value Value for the cookie - * @param string $expire Cookie expiration period - * @param string $path Path - * @param string $domain Domain name - * @param bool $secure If secure - * @param bool $httpOnly If uses only HTTP + * @param string $name HTTP header name + * @param string $value Value for the cookie + * @param string $expire Cookie expiration period + * @param string $path Path + * @param string $domain Domain name + * @param bool $secure If secure + * @param bool $httpOnly If uses only HTTP + * @param ''|'None'|'Lax'|'Strict' $samesite If uses Same-site cookies * * @throws sfException If fails to set the cookie */ - public function setCookie($name, $value, $expire = null, $path = '/', $domain = '', $secure = false, $httpOnly = false) + public function setCookie($name, $value, $expire = null, $path = '/', $domain = '', $secure = false, $httpOnly = false, string $samesite = '') { if (null !== $expire) { if (is_numeric($expire)) { @@ -193,6 +194,7 @@ public function setCookie($name, $value, $expire = null, $path = '/', $domain = 'domain' => $domain, 'secure' => $secure ? true : false, 'httpOnly' => $httpOnly, + 'samesite' => $samesite, ]; } @@ -359,7 +361,14 @@ public function sendHttpHeaders() foreach ($this->cookies as $cookie) { $expire = isset($cookie['expire']) ? $cookie['expire'] : 0; $domain = isset($cookie['domain']) ? $cookie['domain'] : ''; - setrawcookie($cookie['name'], $cookie['value'], $expire, $cookie['path'], $domain, $cookie['secure'], $cookie['httpOnly']); + setrawcookie($cookie['name'], $cookie['value'], [ + 'expires' => $expire, + 'path' => $cookie['path'], + 'domain' => $domain, + 'secure' => $cookie['secure'], + 'httpOnly' => $cookie['httpOnly'], + 'samesite' => $cookie['samesite'], + ]); if ($this->options['logging']) { $this->dispatcher->notify(new sfEvent($this, 'application.log', [sprintf('Send cookie "%s": "%s"', $cookie['name'], $cookie['value'])])); diff --git a/lib/storage/sfSessionStorage.class.php b/lib/storage/sfSessionStorage.class.php index d5dbe91e0..b4ba19da9 100644 --- a/lib/storage/sfSessionStorage.class.php +++ b/lib/storage/sfSessionStorage.class.php @@ -35,7 +35,8 @@ class sfSessionStorage extends sfStorage * * session_cookie_path: Cookie path * * session_cookie_domain: Cookie domain * * session_cookie_secure: Cookie secure - * * session_cookie_httponly: Cookie http only (only for PHP >= 5.2) + * * session_cookie_httponly: Cookie http only + * * session.cookie_samesite: Cookie same site * * The default values for all 'session_cookie_*' options are those returned by the session_get_cookie_params() function * @@ -56,6 +57,7 @@ public function initialize($options = null) 'session_cookie_domain' => $cookieDefaults['domain'], 'session_cookie_secure' => $cookieDefaults['secure'], 'session_cookie_httponly' => isset($cookieDefaults['httponly']) ? $cookieDefaults['httponly'] : false, + 'session_cookie_samesite' => isset($cookieDefaults['samesite']) ? $cookieDefaults['samesite'] : '', 'session_cache_limiter' => null, 'gc_maxlifetime' => 1800, ], $options); @@ -77,7 +79,15 @@ public function initialize($options = null) $domain = $this->options['session_cookie_domain']; $secure = $this->options['session_cookie_secure']; $httpOnly = $this->options['session_cookie_httponly']; - session_set_cookie_params($lifetime, $path, $domain, $secure, $httpOnly); + $samesite = $this->options['session_cookie_samesite']; + session_set_cookie_params([ + 'lifetime' => $lifetime, + 'path' => $path, + 'domain' => $domain, + 'secure' => $secure, + 'httponly' => $httpOnly, + 'samesite' => $samesite, + ]); if (null !== $this->options['session_cache_limiter']) { session_cache_limiter($this->options['session_cache_limiter']); diff --git a/test/unit/response/sfWebResponseTest.php b/test/unit/response/sfWebResponseTest.php index d0d638391..f880c5088 100644 --- a/test/unit/response/sfWebResponseTest.php +++ b/test/unit/response/sfWebResponseTest.php @@ -281,7 +281,7 @@ public function normalizeHeaderName($name) // ->setCookie() ->getCookies() $t->diag('->setCookie() ->getCookies()'); $response->setCookie('foo', 'bar'); -$t->is($response->getCookies(), ['foo' => ['name' => 'foo', 'value' => 'bar', 'expire' => null, 'path' => '/', 'domain' => '', 'secure' => false, 'httpOnly' => false]], '->setCookie() adds a cookie for the response'); +$t->is($response->getCookies(), ['foo' => ['name' => 'foo', 'value' => 'bar', 'expire' => null, 'path' => '/', 'domain' => '', 'secure' => false, 'httpOnly' => false, 'samesite' => '']], '->setCookie() adds a cookie for the response'); // ->setHeaderOnly() ->getHeaderOnly() $t->diag('->setHeaderOnly() ->isHeaderOnly()');