【问题标题】:How can I set the samesite cookie attribute in CakePHP 2.3?如何在 CakePHP 2.3 中设置 samesite cookie 属性?
【发布时间】:2020-11-17 22:53:28
【问题描述】:

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 或某些网络浏览设备和 AJAX 时,您可能希望将该值设置为 false
  • Session.defaults - 用作会话基础的默认配置集。有四个内置函数:php、cake、cache、database。
  • Session.handler - 可用于启用自定义会话处理程序。期望可调用的数组,可与session_save_handler 一起使用。使用此选项会自动将session.save_handler 添加到 ini 数组中。
  • Session.autoRegenerate - 启用此设置,开启会话自动续订,以及 sessionid 经常更改。请参阅 CakeSession::$requestCountdown。
  • Session.ini - 要设置的附加 ini 值的关联数组。

这就是我现在的样子:

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

有解决办法吗?我一直在研究如何使用 php 执行此操作,但我不确定如何编辑 CakePHP 使用我想要的属性创建的会话 cookie,或者一旦创建了 cookie 是否有可能。

【问题讨论】:

  • 你使用的是什么 PHP 版本?
  • @ndm 我使用的是 PHP 5.6

标签: cakephp cookies cakephp-2.3 samesite cakephp-2.x


【解决方案1】:

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

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

自 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 组件和扩展/自定义 response class,您可以在其中相应地覆盖 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;
        }
    }
}
<?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);
        }
    }
}

在前端控制器中注入自定义响应:

// in app/webroot/index.php

App::uses('Network', 'AppResponse');

$Dispatcher = new Dispatcher();
$Dispatcher->dispatch(
    new CakeRequest(),
    new AppResponse()
);

Alias the Cookie component 与自定义组件类:

// in app/Controller/AppController.php

public $components = [
    'Cookie' => [
        'className' => 'AppCookie',
    ],
];

然后在使用之前相应地配置组件:

$this->Cookie->sameSite = 'None';
$this->Cookie->secure = true;

或者直接使用响应对象来设置你的cookies:

$this->response->cookie([
    'name' => 'cookie name',
    'value' => 'cookie value',
    'expire' => time() + (60 * 24),
    'path' => '/',
    'domain' => '',
    'secure' => true,
    'httpOnly' => false,
    'sameSite' => 'None',
]);

【讨论】:

    猜你喜欢
    • 2020-07-07
    • 2020-07-04
    • 2020-04-25
    • 2018-11-21
    • 2019-10-31
    • 2019-06-03
    • 2020-09-24
    • 2020-12-28
    • 2020-04-18
    相关资源
    最近更新 更多