如何在CakePHP 2.3中设置samesite cookie属性?

fafcakar  于 2022-11-12  发布在  PHP
关注(0)|答案(1)|浏览(203)

CakePHP 2.3在core.php文件中设置Session变量(包括cookie属性)。我需要为会话cookie设置samesite=NoneSecure=true,但在配置中似乎没有这些设置,配置中只显示了以下选项:

  • Session.cookie-要使用的Cookie的名称。默认值为“CAKEPHP”
  • Session.timeout-您希望会话存活的分钟数。此超时由CakePHP处理
  • Session.cookieTimeout-您希望会话cookie存活的分钟数。
  • Session.checkAgent-是否希望在启动会话时检查用户代理?在处理旧版本的IE、Chrome Frame或某些Web浏览设备和 AJAX 时,您可能希望将该值设置为false
  • Session.defaults-用作会话基础的默认配置集。有四个内置项:PHP、蛋糕、缓存、数据库。
  • Session.handler-可用于启用自定义会话处理程序。应为可调用对象的数组,该数组可与session_save_handler一起使用。使用此选项将自动将session.save_handler添加到ini数组。
  • Session.autoRegenerate-启用此设置,打开会话的自动续订和经常更改的会话ID。请参阅CakeSession::$requestCountdown。
  • Session.ini-要设置的附加ini值的关联数组。

这是我现在的情况:

Configure::write('Session', array(
                                    'defaults' => 'database',
                                    'handler' => array('model' => 'cake_sessions'),
                                    'timeout' => 60
                                    ));

我一直在研究如何在php中实现这一点,但我不确定如何编辑CakePHP创建的带有我想要的属性的会话cookie,或者在cookie创建后是否可以这样做。

jbose2ul

jbose2ul1#

PHP 7.3之前的版本

在早于PHP 7.3的PHP版本中,可以通过利用cookie路径hack来注入SameSite属性,这包括将更多cookie属性附加到路径,只需用分号关闭路径即可。
只需相应地配置app/Config/core.php中的**session.cookie_path**ini选项,例如,如果应用程序的基路径是/,则如下所示:

Configure::write('Session', [
    'defaults' => 'php',
    'ini' => [
        'session.cookie_path' => '/; SameSite=None',
    ],
]);

当您通过https访问您的站点时,CakePHP会自动配置Secure属性(即session.cookie_secure ini选项)。

从PHP 7.3开始

在PHP 7.3之前的PHP版本中,您将改用**session.cookie_samesite**ini选项:

Configure::write('Session', [
    'defaults' => 'php',
    'ini' => [
        'session.cookie_samesite' => 'None',
    ],
]);

其他Cookie

当然,所有这些都只适用于会话cookie,如果您通过the Cookie component使用额外的cookie,那么您还必须通过相应地修改$path属性来利用路径黑客,并且与会话不同,您必须显式启用安全cookie:

$this->Cookie->path = '/; SameSite=None';
$this->Cookie->secure = true;

对于PHP 7.3+,您必须使用一个自定义/扩展Cookie组件,以及一个扩展/自定义响应类,您可以在其中相应地覆盖CookieComponent::_write()CakeResponse::cookie()CakeResponse::_setCookies()方法,以便该组件允许为同一站点设置一个选项,并且响应将把它传递给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;
        }
    }
}

*http://github.com/cakephp/cakephp/blob/2.3.10/lib/Cake/Controller/Component/CookieComponent.php#L413
*http://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);
        }
    }
}

*http://github.com/cakephp/cakephp/blob/2.3.10/lib/Cake/Network/CakeResponse.php#L1189
*http://github.com/cakephp/cakephp/blob/2.3.10/lib/Cake/Network/CakeResponse.php#L437
*http://github.com/cakephp/cakephp/blob/2.10.22/lib/Cake/Network/CakeResponse.php#L1236
*http://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()
);

*http://github.com/cakephp/cakephp/blob/2.3.10/app/webroot/index.php#L107-L110
*http://github.com/cakephp/cakephp/blob/2.10.22/app/webroot/index.php#L114-L118
使用自定义组件类为Cookie组件创建别名:

// 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',
]);

相关问题