如何告诉 PHP 对跨站点 cookie 使用 SameSite=None?

How to tell PHP to use SameSite=None for cross-site cookies?

根据此处的文章 https://php.watch/articles/PHP-Samesite-cookies and PHP documenation at https://www.php.net/manual/en/session.security.ini.php,此新功能只有 2 个可能的配置选项,在 PHP 7.3 中添加:

  1. session.cookie_samesite=松弛
  2. session.cookie_samesite=严格

然而,根据 Chrome 控制台,这需要设置为 "None":

A cookie associated with a cross-site resource at URL was set without the SameSite attribute. It has been blocked, as Chrome now only delivers cookies with cross-site requests if they are set with SameSite=None and Secure. You can review cookies in developer tools under Application>Storage>Cookies and see more details at URL and URL.

因此,我无法再设置跨站cookies。解决方法是什么?

您可以使用 ini_set 将值设置为“None”。使用该函数时不检查该值是否受支持:

ini_set('session.cookie_samesite', 'None');
session_start();

session_set_cookie_params也可以设置:

session_set_cookie_params(['samesite' => 'None']);
session_start();

php.ini 支持的错误报告是 here


因为 @shrimpwagon said in a session.cookie_secure 必须是 true 才能工作。 PHP 不需要,但浏览器需要。

这个方法对你有帮助

Secure + SameSite=None

下面的 nginx 上添加 header 的属性

location / {

proxy_cookie_path / "/; secure; SameSite=none";

}

它对我有用!

差:

session.cookie_samesite=None

正确:

session.cookie_samesite="None"

说明here

我正在使用 cakephp 1.3。我需要位于 front-end 的后端 cookie,它不是同一个域。 在这里查看详细信息。

ini_set('session.cookie_secure', "1"); ini_set('session.cookie_httponly', "1"); ini_set('session.cookie_samesite','None'); session_start();

php 7.4 phpinfo 中的同一站点 enter image description here

php 7.2 phpinfo 中不存在 Samesite enter image description here

$currentCookieParams = session_get_cookie_params();
$cookie_domain= 'your domain';
if (PHP_VERSION_ID >= 70300) {
session_set_cookie_params([
    'lifetime' =>  $currentCookieParams["lifetime"],
    'path' => '/',
    'domain' => $cookie_domain,
    'secure' => "1",
    'httponly' => "1",
    'samesite' => 'None',
]);
} else {
session_set_cookie_params(
    $currentCookieParams["lifetime"],
    '/; samesite=None',
    $cookie_domain,
    "1",
    "1"
);
}
session_start();

祝你好运

对于 PHP 5.6.40,存在一个不涉及重建 PHP.

的解决方法(路径参数 hack)

如果重建 PHP 二进制文件没有问题,我设法将此功能从 PHP 7.3 移植到 PHP 5.6.40,现在有一个拉取请求。 对于尚未迁移的项目,我需要它。 我知道 5.6 分支已被弃用,我只是分享。

拉取请求: https://github.com/php/php-src/pull/6446

我们的回购有变化: https://github.com/Inducido/php-src/tree/PHP-5.6.40

构建在 Debian 8.11 上测试

新功能

Session: .添加了对 setcookie() 的 SameSite cookie 指令的支持, setrawcookie() 和 session_set_cookie_params()。 来自 PHP 7.x 分支的端口 他们在最后都有一个“samesite”附加参数(字符串)

原型:

bool setcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly[, string samesite]]]]]]])
bool setrawcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly[, string samesite]]]]]]])
void session_set_cookie_params(int lifetime [, string path [, string domain [, bool secure[, bool httponly[, string samesite]]]]])
(session_get_cookie_params updated too)

INI 文件处理的变化

  • session.cookie_samesite .允许为 cookie 设置 SameSite 指令的新 INI 选项。默认值 为“”(空字符串),因此未设置 SameSite 指令。可以设置为“宽松” 或“严格”,或设置相应 SameSite 指令的“None”。 使用“None”时,确保包含引号,因为 none 被解释为 就像 ini 文件中的 false

这解决了 Chrome 中的“此 Set-Cookie 由于用户偏好而被阻止”的问题。

如果你使用nginx,你也可以使用lua修改cookie。它有点老套,但我发现它适用于遗留网站:

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    location ~ \.php$ {
            include snippets/fastcgi-php.conf;

            fastcgi_pass unix:/run/php/php5.6-fpm.sock;

            # This is the relevant part:
            header_filter_by_lua '
                    local cookies = ngx.header.set_cookie
                    if cookies then
                            if type(cookies) ~= "table" then
                                    cookies = {cookies}
                            end
                            local gsub = string.gsub
                            local changed
                            for i, cookie in ipairs(cookies) do
                                    local new_cookie = gsub(cookie, "^PHPSESSION=(.*)", "PHPSESSION=%1; Samesite=strict", 1)
                                    if new_cookie ~= cookie then
                                            cookies[i] = new_cookie
                                            changed = true
                                    end
                            end
                            if changed then
                                    ngx.header.set_cookie = cookies
                            end
                    end
            ';
            # End Lua
    }

您可能需要调整正则表达式 (gsub),但我发现它运行良好。