如何在CakePHP 2.3中设置samesite cookie属性? [英] How can I set the samesite cookie attribute in CakePHP 2.3?
问题描述
CakePHP 2.3在core.php文件中设置会话变量(包括cookie属性).我需要为会话cookie设置 samesite = None
和 Secure = true
,但是在配置中似乎没有那些可用的设置,仅显示以下内容选项:
CakePHP 2.3 sets the Session variables (including cookie attributes) in the core.php file. I need to set samesite=None
and Secure=true
for the session cookie, but it doesn't appear to have those settings available in the configuration, which shows only the following options:
-
Session.cookie
-要使用的Cookie的名称.默认为'CAKEPHP' -
Session.timeout
-您希望会话存活的分钟数.此超时由CakePHP处理 -
Session.cookieTimeout
-您希望会话cookie存活的分钟数. -
Session.checkAgent
-您是否要在启动会话时检查用户代理?处理旧版本的IE,Chrome Frame或某些网络浏览设备和AJAX时,您可能需要将该值设置为false. -
Session.defaults
-设置为会话基础的默认配置.共有四个内置函数:php,cake,cache,数据库. -
Session.handler
-可用于启用自定义会话处理程序.需要一个可调用的数组,可以与session_save_handler
一起使用.使用此选项将自动将session.save_handler
添加到ini数组. -
Session.autoRegenerate
-启用此设置,打开会话自动更新,并经常更改的sessionid.请参阅CakeSession :: $ requestCountdown. -
Session.ini
-要设置的其他ini值的关联数组.
Session.cookie
- The name of the cookie to use. Defaults to 'CAKEPHP'Session.timeout
- The number of minutes you want sessions to live for. This timeout is handled by CakePHPSession.cookieTimeout
- The number of minutes you want session cookies to live for.Session.checkAgent
- Do you want the user agent to be checked when starting sessions? You might want to set the value to false, when dealing with older versions of IE, Chrome Frame or certain web-browsing devices and AJAXSession.defaults
- The default configuration set to use as a basis for your session. There are four builtins: php, cake, cache, database.Session.handler
- Can be used to enable a custom session handler. Expects an array of of callables, that can be used withsession_save_handler
. Using this option will automatically addsession.save_handler
to the ini array.Session.autoRegenerate
- Enabling this setting, turns on automatic renewal of sessions, and sessionids that change frequently. See CakeSession::$requestCountdown.Session.ini
- An associative array of additional ini values to set.
这就是我现在的样子:
Configure::write('Session', array(
'defaults' => 'database',
'handler' => array('model' => 'cake_sessions'),
'timeout' => 60
));
是否有解决方法?我一直在研究如何使用php进行此操作,但不确定如何使用我想要的属性来编辑CakePHP创建的会话cookie,或者一旦创建cookie便完全可以做到这一点.>
Is there a workaround for this? I've been looking at how to do this with php but I'm not sure how I would edit the session cookie that CakePHP creates with the attributes I want, or if that is possible at all once the cookie has been created.
推荐答案
在PHP 7.3之前
在PHP 7.3之前的PHP版本中,您可以利用cookie路径hack注入 SameSite
属性,该cookie包含通过在路径中附加cookie属性,只需使用分号.
Before PHP 7.3
In PHP versions earlier than PHP 7.3, you can inject the SameSite
attribute by utilizing the cookie path hack, which consists of appending further cookie attributes to the path, by simply closing the path of with a semicolon.
只需配置 <相应地 app/Config/core.php
中的code> session.cookie_path ini选项,例如,如果您的应用程序的基本路径是/
:
Simply configure the session.cookie_path
ini option in app/Config/core.php
accordingly, for example like this in case your application's base path is /
:
Configure::write('Session', [
'defaults' => 'php',
'ini' => [
'session.cookie_path' => '/; SameSite=None',
],
]);
当您通过 https
访问站点时,CakePHP将自动配置 Secure
属性(即 session.cookie_secure
ini选项).>.
The Secure
attribute (ie the session.cookie_secure
ini option) will automatically be configured by CakePHP when you're visiting your site via https
.
In PHP versions as of PHP 7.3 you would use the session.cookie_samesite
ini option instead:
Configure::write('Session', [
'defaults' => 'php',
'ini' => [
'session.cookie_samesite' => 'None',
],
]);
其他cookie
Other cookies
All of this of course only applies to session cookies, if you're using additional cookies via the Cookie component, then you'd have to utilize the path hack there too, by modifying the $path
property accordingly, and unlike with sessions, you'd have to explicitly enable secure cookies:
$this->Cookie->path = '/; SameSite=None';
$this->Cookie->secure = true;
在PHP 7.3+中,您必须使用自定义/扩展的cookie组件,以及扩展/自定义的 setcookie()
调用
With PHP 7.3+ you'd have to use a custom/extended cookie component, and an 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()
call.
示例:
<?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
在前端控制器中注入自定义响应:
Inject the custom response in the front controller:
// 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
为 Cookie别名代码>组件
和自定义组件类:
Alias the Cookie
component with the custom component class:
// in app/Controller/AppController.php
public $components = [
'Cookie' => [
'className' => 'AppCookie',
],
];
,然后在使用它之前相应地配置该组件:
and then configure the component accordingly before using it:
$this->Cookie->sameSite = 'None';
$this->Cookie->secure = true;
或直接使用响应对象设置您的cookie:
or use the response object directly to set your cookies:
$this->response->cookie([
'name' => 'cookie name',
'value' => 'cookie value',
'expire' => time() + (60 * 24),
'path' => '/',
'domain' => '',
'secure' => true,
'httpOnly' => false,
'sameSite' => 'None',
]);
这篇关于如何在CakePHP 2.3中设置samesite cookie属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!