如何告诉 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 中添加:
- session.cookie_samesite=松弛
- 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),但我发现它运行良好。
根据此处的文章 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 中添加:
- session.cookie_samesite=松弛
- 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 withSameSite=None
andSecure
. 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),但我发现它运行良好。