Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
SameSite Cookie Middleware (PSR-15)

Sending SameSite cookies in PHP

Since PHP 7.3+ it's possible to send SameSite cookies.

This makes CSRF prevention techniques obsolete.

Further details can be found here:

More details

Keywords: SameSite, Cookie, PHP, Slim 4, Middleware, CSRF, Security, Session

<?php
namespace App\Middleware;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
/**
* SameSite Cookie Middleware.
*/
final class SameSiteCookieMiddleware implements MiddlewareInterface
{
/**
* @var string
*/
private $sameSite;
/**
* @var bool
*/
private $httpOnly;
/**
* @var bool
*/
private $secure;
/**
* The constructor.
*
* @param string $sameSite Send cookie only via a href link. Values: 'Lax' or 'Strict'.
* @param bool $httpOnly Prevents cookies from being read by scripts. Should be enabled.
* @param bool $secure Provide cookies only via ssl. Should be enabled in production.
*/
public function __construct(string $sameSite = 'Lax', bool $httpOnly = true, bool $secure = false)
{
$this->sameSite = $sameSite;
$this->httpOnly = $httpOnly;
$this->secure = $secure;
}
/**
* Invoke middleware.
*
* @param ServerRequestInterface $request The request
* @param RequestHandlerInterface $handler The handler
*
* @return ResponseInterface The response
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$response = $handler->handle($request);
$sessionId = session_id();
$sessionName = session_name();
$params = session_get_cookie_params();
if (version_compare(PHP_VERSION, '7.3.0') >= 0) {
// Remove invalid key
unset($params['lifetime']);
$params['samesite'] = $this->sameSite;
$params['httponly'] = $this->httpOnly;
$params['secure'] = $this->secure;
setcookie($sessionName, $sessionId, $params);
return $response;
}
// For older PHP versions
$cookieValues = [
sprintf('%s=%s;', $sessionName, $sessionId),
sprintf('path=%s;', $params['path']),
];
if ($this->secure) {
$cookieValues[] = 'Secure;';
}
if ($this->httpOnly) {
$cookieValues[] = 'HttpOnly;';
}
if ($this->sameSite) {
$cookieValues[] = sprintf('SameSite=%s;', $this->sameSite);
}
//$response = $response->withHeader('Set-Cookie', implode(' ', $cookieValues));
header('Set-Cookie: ' . implode(' ', $cookieValues));
return $response;
}
}
@peter279k

This comment has been minimized.

Copy link

commented Sep 7, 2019

The SameSite option is available on php-7.3+ and some explanations are available on setcookie function usage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.