Search code examples
phpsetcookiesamesite

PHP setcookie function including samesite parameter does not work


I have a fully working setcookie() php function running using these params...

<?php

setcookie(
  '_siteauth', 
  Crypt::encrypt(site()->password),
  time() + 86400,
  '/',
);

?>

The code above sets a cookie everytime with no issues!

But as soon as I attempt to use samesite option the cookie never sets... which is a problem.

I am not running this in a iFrame. I am testing this locally using dockers wordpress image, which I cant see being a problem.

At first after all the online reading, I thought it might be a PHP version conflict, but it failed to work in either tests pre/post PHP version 7.3.0.

After reading https://www.php.net/manual/en/function.setcookie.php

...it says options can be set as associative array including expires, path, domain, secure, httponly and samesite, but everytime I try this php setcookie method it does not set.

This is my locally dumped $_SERVER['HTTP_HOST'] result...

demo.local.mydomain.com

Here are all my local tested code attempts, using $_SERVER['HTTP_HOST'] for domain...

<?php

setcookie(
    '_siteauth',
    Crypt::encrypt(site()->password), 
    [
        'expires' => time() + 86400,
        'path' => '/',
        'domain' => $_SERVER['HTTP_HOST'],
        'samesite' => 'None',
        'secure' => false,
        'httponly' => false
    ]
);

?>
<?php

setcookie(
    '_siteauth',
    Crypt::encrypt(site()->password),
    time() + 86400,
    '/; SameSite=none'
);

?>
<?php

setcookie(
    '_siteauth',
    Crypt::encrypt(site()->password),
    [
        'expires' => time() + 86400,
        'path' => '/',
        'domain' => $_SERVER['HTTP_HOST'],
        'secure' => false,
        'httponly' => false,
        'samesite' => 'None'
    ]
);

?>

And none of these code examples save the _siteauth cookie when executed.

I've tried every variation of php version setcookie() including the samesite key and value but no cookie is saved.

The reason I am changing my previous setcookie() script is because there was a change early in 2020 in chrome with iframe cookie policies, defaulting to samesite Lax. So I need to force samesite None when setting my cookie.

https://web.dev/samesite-cookies-explained/
https://web.dev/samesite-cookie-recipes/

If anyone can see where I'm going wrong, help would be amazing.


Solution

  • When you set a cookie with SameSite=None it'll be blocked (by the browser) unless it also has Secure, which is omitted/set to false in the code snippets.

    setcookie(
        '_siteauth',
        Crypt::encrypt(site()->password), 
        [
            'expires' => time() + 86400,
            'path' => '/',
            'domain' => $_SERVER['HTTP_HOST'],
            'samesite' => 'None',
            'secure' => true,
        ]
    );