如何在 CakePHP 2.3 中设置 samesite cookie 属性?
How can I set the samesite cookie attribute in CakePHP 2.3?
CakePHP 2.3 在 core.php 文件中设置 Session 变量(包括 cookie 属性)。我需要为会话 cookie 设置 samesite=None
和 Secure=true
,但在配置中似乎没有这些设置可用,它仅显示以下选项:
Session.cookie
- 要使用的 cookie 的名称。默认为 'CAKEPHP'
Session.timeout
- 您希望会话持续的分钟数。此超时由 CakePHP 处理
Session.cookieTimeout
- 您希望会话 cookie 存活的分钟数。
Session.checkAgent
- 您是否希望在启动会话时检查用户代理?在处理旧版本的 IE、Chrome Frame 或某些网络浏览设备和 AJAX 时,您可能希望将该值设置为 false
Session.defaults
- 用作会话基础的默认配置集。有四个内置函数:php、cake、缓存、数据库。
Session.handler
- 可用于启用自定义会话处理程序。需要一组可调用对象,可以与 session_save_handler
一起使用。使用此选项会自动将 session.save_handler
添加到 ini 数组。
Session.autoRegenerate
- 启用此设置,打开会话的自动更新,并且
经常变化的sessionids。请参见 CakeSession::$requestCountdown。
Session.ini
- 要设置的附加 ini 值的关联数组。
我现在是这样的:
Configure::write('Session', array(
'defaults' => 'database',
'handler' => array('model' => 'cake_sessions'),
'timeout' => 60
));
有解决办法吗?我一直在研究如何使用 php 来做到这一点,但我不确定我将如何编辑 CakePHP 使用我想要的属性创建的会话 cookie,或者一旦 cookie 是否可行已创建。
之前 PHP 7.3
在 PHP 早于 PHP 7.3 的版本中,您可以通过利用 cookie 路径 hack 注入 SameSite
属性,其中包括将更多 cookie 属性附加到路径,通过只需用分号关闭路径。
只需相应地在 app/Config/core.php
中配置 session.cookie_path
ini 选项,例如,如果您的应用程序的基本路径是 /
:
Configure::write('Session', [
'defaults' => 'php',
'ini' => [
'session.cookie_path' => '/; SameSite=None',
],
]);
当您通过 https
访问您的站点时,Secure
属性(即 session.cookie_secure
ini 选项)将由 CakePHP 自动配置。
截至 PHP 7.3
从 PHP 7.3 开始的 PHP 版本中,您将使用 session.cookie_samesite
ini 选项代替:
Configure::write('Session', [
'defaults' => 'php',
'ini' => [
'session.cookie_samesite' => 'None',
],
]);
其他饼干
所有这些当然只适用于会话 cookie,如果您通过 the Cookie component 使用其他 cookie,那么您也必须通过修改 $path
属性 因此,与会话不同,您必须明确启用安全 cookie:
$this->Cookie->path = '/; SameSite=None';
$this->Cookie->secure = true;
对于 PHP 7.3+,您必须使用 custom/extended cookie 组件和 extended/custom response class where you'd override the CookieComponent::_write()
, CakeResponse::cookie()
and CakeResponse::_setCookies()
methods accordingly, so that the component allows to set an option for same site, and the response will pass it over to the setcookie()
调用。
示例:
<?php
// in app/Controller/Component/AppCookieComponent.php
App::uses('CookieComponent', 'Controller/Component');
class AppCookieComponent extends CookieComponent
{
public $sameSite = 'Lax';
protected function _write($name, $value)
{
$this->_response->cookie(array(
'name' => $this->name . $name,
'value' => $this->_encrypt($value),
'expire' => $this->_expires,
'path' => $this->path,
'domain' => $this->domain,
'secure' => $this->secure,
'httpOnly' => $this->httpOnly,
'sameSite' => $this->sameSite,
));
if (!empty($this->_reset)) {
$this->_expires = $this->_reset;
$this->_reset = null;
}
}
}
- https://github.com/cakephp/cakephp/blob/2.3.10/lib/Cake/Controller/Component/CookieComponent.php#L413
- https://github.com/cakephp/cakephp/blob/2.10.22/lib/Cake/Controller/Component/CookieComponent.php#L393
<?php
// in app/Network/AppResponse.php
App::uses('CakeResponse', 'Network');
class AppResponse extends CakeResponse
{
public function cookie($options = null)
{
$options += [
'sameSite' => 'Lax',
];
return parent::cookie($options);
}
protected function _setCookies()
{
foreach ($this->_cookies as $name => $cookie) {
$options = [
'expires' => $cookie['expire'],
'path' => $cookie['path'],
'domain' => $cookie['domain'],
'secure' => $cookie['secure'],
'httponly' => $cookie['httpOnly'],
'samesite' => $cookie['sameSite'],
];
setcookie($name, $cookie['value'], $options);
}
}
}
- https://github.com/cakephp/cakephp/blob/2.3.10/lib/Cake/Network/CakeResponse.php#L1189
- https://github.com/cakephp/cakephp/blob/2.3.10/lib/Cake/Network/CakeResponse.php#L437
- https://github.com/cakephp/cakephp/blob/2.10.22/lib/Cake/Network/CakeResponse.php#L1236
- https://github.com/cakephp/cakephp/blob/2.10.22/lib/Cake/Network/CakeResponse.php#L454
在前端控制器中注入自定义响应:
// in app/webroot/index.php
App::uses('Network', 'AppResponse');
$Dispatcher = new Dispatcher();
$Dispatcher->dispatch(
new CakeRequest(),
new AppResponse()
);
- https://github.com/cakephp/cakephp/blob/2.3.10/app/webroot/index.php#L107-L110
- https://github.com/cakephp/cakephp/blob/2.10.22/app/webroot/index.php#L114-L118
Alias the Cookie
component 与自定义组件 class:
// in app/Controller/AppController.php
public $components = [
'Cookie' => [
'className' => 'AppCookie',
],
];
然后在使用之前相应地配置组件:
$this->Cookie->sameSite = 'None';
$this->Cookie->secure = true;
或直接使用响应对象来设置您的 cookie:
$this->response->cookie([
'name' => 'cookie name',
'value' => 'cookie value',
'expire' => time() + (60 * 24),
'path' => '/',
'domain' => '',
'secure' => true,
'httpOnly' => false,
'sameSite' => 'None',
]);
CakePHP 2.3 在 core.php 文件中设置 Session 变量(包括 cookie 属性)。我需要为会话 cookie 设置 samesite=None
和 Secure=true
,但在配置中似乎没有这些设置可用,它仅显示以下选项:
Session.cookie
- 要使用的 cookie 的名称。默认为 'CAKEPHP'Session.timeout
- 您希望会话持续的分钟数。此超时由 CakePHP 处理
Session.cookieTimeout
- 您希望会话 cookie 存活的分钟数。Session.checkAgent
- 您是否希望在启动会话时检查用户代理?在处理旧版本的 IE、Chrome Frame 或某些网络浏览设备和 AJAX 时,您可能希望将该值设置为 false
Session.defaults
- 用作会话基础的默认配置集。有四个内置函数:php、cake、缓存、数据库。Session.handler
- 可用于启用自定义会话处理程序。需要一组可调用对象,可以与session_save_handler
一起使用。使用此选项会自动将session.save_handler
添加到 ini 数组。Session.autoRegenerate
- 启用此设置,打开会话的自动更新,并且 经常变化的sessionids。请参见 CakeSession::$requestCountdown。Session.ini
- 要设置的附加 ini 值的关联数组。
我现在是这样的:
Configure::write('Session', array(
'defaults' => 'database',
'handler' => array('model' => 'cake_sessions'),
'timeout' => 60
));
有解决办法吗?我一直在研究如何使用 php 来做到这一点,但我不确定我将如何编辑 CakePHP 使用我想要的属性创建的会话 cookie,或者一旦 cookie 是否可行已创建。
之前 PHP 7.3
在 PHP 早于 PHP 7.3 的版本中,您可以通过利用 cookie 路径 hack 注入 SameSite
属性,其中包括将更多 cookie 属性附加到路径,通过只需用分号关闭路径。
只需相应地在 app/Config/core.php
中配置 session.cookie_path
ini 选项,例如,如果您的应用程序的基本路径是 /
:
Configure::write('Session', [
'defaults' => 'php',
'ini' => [
'session.cookie_path' => '/; SameSite=None',
],
]);
当您通过 https
访问您的站点时,Secure
属性(即 session.cookie_secure
ini 选项)将由 CakePHP 自动配置。
截至 PHP 7.3
从 PHP 7.3 开始的 PHP 版本中,您将使用 session.cookie_samesite
ini 选项代替:
Configure::write('Session', [
'defaults' => 'php',
'ini' => [
'session.cookie_samesite' => 'None',
],
]);
其他饼干
所有这些当然只适用于会话 cookie,如果您通过 the Cookie component 使用其他 cookie,那么您也必须通过修改 $path
属性 因此,与会话不同,您必须明确启用安全 cookie:
$this->Cookie->path = '/; SameSite=None';
$this->Cookie->secure = true;
对于 PHP 7.3+,您必须使用 custom/extended cookie 组件和 extended/custom response class where you'd override the CookieComponent::_write()
, CakeResponse::cookie()
and CakeResponse::_setCookies()
methods accordingly, so that the component allows to set an option for same site, and the response will pass it over to the setcookie()
调用。
示例:
<?php
// in app/Controller/Component/AppCookieComponent.php
App::uses('CookieComponent', 'Controller/Component');
class AppCookieComponent extends CookieComponent
{
public $sameSite = 'Lax';
protected function _write($name, $value)
{
$this->_response->cookie(array(
'name' => $this->name . $name,
'value' => $this->_encrypt($value),
'expire' => $this->_expires,
'path' => $this->path,
'domain' => $this->domain,
'secure' => $this->secure,
'httpOnly' => $this->httpOnly,
'sameSite' => $this->sameSite,
));
if (!empty($this->_reset)) {
$this->_expires = $this->_reset;
$this->_reset = null;
}
}
}
- https://github.com/cakephp/cakephp/blob/2.3.10/lib/Cake/Controller/Component/CookieComponent.php#L413
- https://github.com/cakephp/cakephp/blob/2.10.22/lib/Cake/Controller/Component/CookieComponent.php#L393
<?php
// in app/Network/AppResponse.php
App::uses('CakeResponse', 'Network');
class AppResponse extends CakeResponse
{
public function cookie($options = null)
{
$options += [
'sameSite' => 'Lax',
];
return parent::cookie($options);
}
protected function _setCookies()
{
foreach ($this->_cookies as $name => $cookie) {
$options = [
'expires' => $cookie['expire'],
'path' => $cookie['path'],
'domain' => $cookie['domain'],
'secure' => $cookie['secure'],
'httponly' => $cookie['httpOnly'],
'samesite' => $cookie['sameSite'],
];
setcookie($name, $cookie['value'], $options);
}
}
}
- https://github.com/cakephp/cakephp/blob/2.3.10/lib/Cake/Network/CakeResponse.php#L1189
- https://github.com/cakephp/cakephp/blob/2.3.10/lib/Cake/Network/CakeResponse.php#L437
- https://github.com/cakephp/cakephp/blob/2.10.22/lib/Cake/Network/CakeResponse.php#L1236
- https://github.com/cakephp/cakephp/blob/2.10.22/lib/Cake/Network/CakeResponse.php#L454
在前端控制器中注入自定义响应:
// in app/webroot/index.php
App::uses('Network', 'AppResponse');
$Dispatcher = new Dispatcher();
$Dispatcher->dispatch(
new CakeRequest(),
new AppResponse()
);
- https://github.com/cakephp/cakephp/blob/2.3.10/app/webroot/index.php#L107-L110
- https://github.com/cakephp/cakephp/blob/2.10.22/app/webroot/index.php#L114-L118
Alias the Cookie
component 与自定义组件 class:
// in app/Controller/AppController.php
public $components = [
'Cookie' => [
'className' => 'AppCookie',
],
];
然后在使用之前相应地配置组件:
$this->Cookie->sameSite = 'None';
$this->Cookie->secure = true;
或直接使用响应对象来设置您的 cookie:
$this->response->cookie([
'name' => 'cookie name',
'value' => 'cookie value',
'expire' => time() + (60 * 24),
'path' => '/',
'domain' => '',
'secure' => true,
'httpOnly' => false,
'sameSite' => 'None',
]);