'How to tell PHP to use SameSite=None for cross-site cookies?
According to the article here https://php.watch/articles/PHP-Samesite-cookies and PHP documenation at https://www.php.net/manual/en/session.security.ini.php, There are only 2 possible config options for this new feature, added in PHP 7.3:
- session.cookie_samesite=Lax
- session.cookie_samesite=Strict
Yet, according to the Chrome console, this needs to be set to "None":
A cookie associated with a cross-site resource at URL was set without the
SameSiteattribute. It has been blocked, as Chrome now only delivers cookies with cross-site requests if they are set withSameSite=NoneandSecure. You can review cookies in developer tools under Application>Storage>Cookies and see more details at URL and URL.
Because of this, I can no longer set cross-site cookies. What is the workaround?
Solution 1:[1]
You can set the value to "None" using ini_set. There's no check that the value is supported when that function is used:
ini_set('session.cookie_samesite', 'None');
session_start();
session_set_cookie_params can also set it:
session_set_cookie_params(['samesite' => 'None']);
session_start();
The bug report for this to be supported in php.ini is here.
As @shrimpwagon said in a comment below, session.cookie_secure must be true for this to work. PHP doesn't require it, but browsers do.
Solution 2:[2]
ini_set('session.cookie_secure', "1"); ini_set('session.cookie_httponly', "1"); ini_set('session.cookie_samesite','None'); session_start();
php 7.4 samesite in phpinfo enter image description here
php 7.2 samesite does not exist in phpinfo 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();
???? ?????
Solution 3:[3]
Solution 4:[4]
This method can be helpful for u
Add header's attributes on nginx below Secure + SameSite=None
location / {
proxy_cookie_path / "/; secure; SameSite=none";
}
It's working on me!
Solution 5:[5]
I am using cakephp 1.3. I need backend cookie at front-end that is not same domain. check in detail here.
Solution 6:[6]
For PHP 5.6.40, there exists a workaround (the hack on path parameter) which does not involve rebuilding PHP.
If you have no problem rebuilding the PHP binary, I managed to port this feature from PHP 7.3 to PHP 5.6.40, and there is now a pull request. I needed it for our projects that aren't migrated yet. I know 5.6 branch is deprecated, I am just sharing.
Pull request: https://github.com/php/php-src/pull/6446
Our repo with the changes: https://github.com/Inducido/php-src/tree/PHP-5.6.40
Build tested on Debian 8.11
New Feature
Session: . Added support for the SameSite cookie directive for setcookie(), setrawcookie() and session_set_cookie_params(). Port from PHP 7.x branch they all have an "samesite" additionnal parameter at the very end (string)
prototypes:
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)
Changes to INI File Handling
- session.cookie_samesite
. New INI option to allow to set the SameSite directive for cookies. Defaults
to "" (empty string), so no SameSite directive is set. Can be set to "Lax"
or "Strict", or "None" which sets the respective SameSite directive.
when using "None", make sure to include the quotes, as
noneis interpreted likefalsein ini files.
This solves the issue "This Set-Cookie was blocked due to user preferences" in Chrome.
Solution 7:[7]
If you use nginx, you can also modify the cookie using lua. It is a bit hacky, but I found it to be working well for legacy sites:
# 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
}
You might need to adapt the regex (gsub), but I found it works well.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | vitaliytv |
| Solution 4 | Community |
| Solution 5 | Sandeep Sherpur |
| Solution 6 | |
| Solution 7 | ronix75 |
