I recently read \"RFC 6265\" on the attribute \"Same Site\", I looked at some articles that talked about that in April 2016, \"same-site\" attribute has been implemented for
Based on Steffen's answer above, this is the method I am using to support both php <= 7.2 and php >= 7.3:
/**
* Support samesite cookie flag in both php 7.2 (current production) and php >= 7.3 (when we get there)
* From: https://github.com/GoogleChromeLabs/samesite-examples/blob/master/php.md and https://stackoverflow.com/a/46971326/2308553
* * @param [type] $name
* @param [type] $value
* @param [type] $expire
* @param [type] $path
* @param [type] $domain
* @param [type] $secure
* @param [type] $httponly
* @param [type] $samesite
* @return void
*/
function setcookieSameSite($name, $value, $expire, $path, $domain, $secure, $httponly, $samesite="None")
{
if (PHP_VERSION_ID < 70300) {
setcookie($name, $value, $expire, "$path; samesite=$samesite", $domain, $secure, $httponly);
}
else {
setcookie($name, $value, [
'expires' => $expire,
'path' => $path,
'domain' => $domain,
'samesite' => $samesite,
'secure' => $secure,
'httponly' => $httponly,
]);
}
}
Worth mentioning that Safari 12 on both macOS and iOS will not recognise a value of None for the SameSite attribute, and default to a value of Strict.
Version 13 will accept "None", but without explicitly setting a value, it defaults to "Lax".
Here's a good explanation:
https://www.thinktecture.com/en/identity/samesite/samesite-in-a-nutshell/
There are a lot of examples showing how to set this attribute, but not many explanations of why.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#SameSite_attribute
If a cookie is needed to be sent cross-origin, opt out of the SameSite restriction by using the None directive. The None directive requires that the Secure attribute also be used.
The examples that are setting SameSite
to None
or Lax
are only appropriate for cross-domain scenarios. If your code isn't cross-domain, use Strict
.
[Important update: As @caw pointed out below, this hack WILL BREAK in PHP 7.3. Stop using it now to save yourself from unpleasant surprises! Or at least wrap it in a PHP version check like if (PHP_VERSION_ID < 70300) { ... } else { ... }
.]
It seems like you can abuse the "path" or "domain" parameter of PHP's "setcookie" function to sneak in the SameSite attribute because PHP does not escape semicolons:
setcookie('samesite-test', '1', 0, '/; samesite=strict');
Then PHP sends the following HTTP header:
Set-Cookie: samesite-test=1; path=/; samesite=strict
I've just discovered this a few minutes ago, so please do your own testing! I'm using PHP 7.1.11.
I wrote a class for setting samesite cookies.
https://github.com/ovunctukenmez/SameSiteCookieSetter
It works on all PHP versions. It also checks if the browser supports samesite parameter properly.
Here is the usage:
//set samesite strict php cookie
SameSiteCookieSetter::setcookie('samesite_test','testvalue', array('samesite' => 'Strict'));
For local development PHPSESSID problems;
First, you have to set "SameSite by default cookies" and "Cookies without SameSite must be secure" by opening chrome flag management page and restart chrome ;
chrome://flags/#same-site-by-default-cookies
If you are working on local environment without https and using hosts file ip mapping to work with live domain. Cookie for PHPSESSID can not be set and you will not have a php session. if you visited https site even once, that secure cookie will be set already. So you need to delete it first. Because you can't set a non-secure cookie if you have already have a secure cookie set with the same name even if you disabled chrome same-site flags.
You should change your hosts file to open live site (with https) and open developer tools / Application and delete the cookie set with https. After this without reloading live site, set your hosts file again to work with local and open non-https local driven website. Now your PHPSESSID (and other cookies) will be set.