1 minute read

When working with shared caches like Varnish or Nginx, cookies will kill everything you are trying to do.

The idea is that since a cookie can be used by the backend to modify the reply, like being logged in as a user, the shared does not take the chance and refuse to cache it. This behaviour can be modified, especially in the case of Google Analytics cookies, but for the PHP session cookie, you will typically want it.

However, it is important, for a useful usage of your shared cache, to only start a session when you really need it and destroy it when it is not needed anymore. PHP’s session_start specifically mentions that is does not unset the associated cookie.

So the idea is to start a session when you need it; for example, in a login page. This will send a header to the client, setting a cookie and the cookie will get sent back on every request. Therefore, in some global file, you can detect this cookie and reload the session. At last, on the logout, clear everything.

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
# global.php
# global.php
# In some global configuration file,
# Start the session only if the cookie is present
if (isset($_COOKIE[session_name()])) { 
  session_start(); 
}
# In the same file or elsewhere, after the previous lines:
if (isset($_SESSION['userid'])) { 
  # If the session has been loaded and the userid is detected, set it
  $userid = $_SESSION['userid']; 
}
1
2
3
4
5
6
<?php 
# login.php
# login.php
# We start a session if it not already started
session_id() == '' && session_start(); 
$_SESSION['userid'] = '1';
1
2
3
4
5
6
7
8
<?php
# logout.php
# logout.php
session_start(); 
# Destroy the session, this is for the current request
session_destroy();
# Ensure that the cookie is destructed by setting a date in the past
setcookie(session_name(), false, time() - 3600);

View Gist