Cookie: cosa sono e come gestirli in PHP

Cookie: cosa sono e come gestirli in PHP

Per sua natura, il protocollo HTTP è stateless (senza stato), ossia non consente di conservare lo stato dell'utente tra una richiesta HTTP e la successiva.

Per ovviare a questo problema, gli sviluppatori web possono fare affidamento sul meccanismo dei cookie.

In questa guida vedremo cosa sono i cookie e il loro funzionamento, i casi di utilizzo e come crearli e accedervi in PHP attraverso la variabile superglobale $_COOKIE.

I cookie sono piccoli file di testo che consentono di memorizzare dati sul computer dell'utente. Sono in genere utilizzati per tenere traccia dell'utente che visita per la prima volta un sito web e poter personalizzare le pagine quando lo stesso utente visiterà nuovamente quel sito.

Dato che i cookie possono contenere informazioni sensibili legate alla privacy utente, il loro utilizzo nei siti web è regolamentato da un provvedimento del Garante dell'8 maggio 2014 e dal GDPR, il regolamento generale sulla protezione dei dati entrato in vigore a maggio 2018.

Funzionamento

Tecnicamente i cookie sono degli header HTTP inviati dal server al client. Sono composti da una coppia chiave/valore e una serie di direttive opzionali.

Vediamo un esempio

Set-Cookie: session_id=1234;
Set-Cookie: session_id=1234; Expires=Fri, 30 Aug 2019 07:28:00 GMT;
Set-Cookie: session_id=1234; Max-Age=3600
Set-Cookie: session_id=1234; Domain=guidaphp.it
Set-Cookie: session_id=1234; Path=/
Set-Cookie: session_id=1234; Secure
Set-Cookie: session_id=1234; HttpOnly

L'intestazione Set-Cookie imposta un cookie di nome session_id sul browser dell'utente, assegnandogli il valore 1234.

Nelle righe successive viene impostato lo stesso cookie con alcune direttive opzionali che elenchiamo di seguito:

  • Expires: imposta la data di validità del cookie. Se non specificato, il cookie sarà valido fino alla fine della sessione, ossia alla chiusura del browser.
  • Max-age: è un altro modo di indicare il periodo di vita del cookie. Il valore in questo caso deve essere in secondi.
  • Domain: specifica per quali domini verranno utilizzati i cookie.
  • Path: indica il percorso URL associato al cookie.
  • Secure: indica che i cookie verranno inviati solamente su connessione sicura (HTTPS).
  • HttpOnly: indica che i cookie non sono accessibili via Javascript tramite document.cookie. Questo limita la possibilità di attacchi di tipo XSS.

L'esempio precedente può essere anche riscritto accorpando le direttive in un'unica riga

Set-Cookie: session_id=1234; Expires=Fri, 30 Aug 2019 07:28:00 GMT; Max-Age=3600; Domain=guidaphp.it; Path=/; Secure; HttpOnly

Utilizzi

I cookie sono prevalentemente utilizzati per funzionalità di autenticazione, tracciatura di sessioni e memorizzazione di informazioni riguardanti gli utenti che accedono a un sito.

Nello specifico i cookie sono utilizzati per:

  • Memorizzare il login utente ad un'area riservata. È la tipica spunta "ricordami" che vediamo ad esempio su alcuni forum.
  • Personalizzare l'esperienza di navigazione sulla base delle preferenze dell'utente. Ad esempio, su siti multilingua è possibile memorizzare la lingua dell'utente (ricavata tramite la variabile globale $_SERVER['HTTP_ACCEPT_LANGUAGE']) e, nelle successive visite, reindirizzare l'utente alla versione nella sua lingua.
  • Tenere traccia dei prodotti del carrello della spesa su siti eCommerce.
  • Tracciare i siti già visitati da un utente e ricavare informazioni da usare per mostrargli banner pubblicitari in linea con le sue preferenze.
  • Tracciare il numero di visite dello stesso utente ad un sito web.

Nota: è assolutamente sconsigliato archiviare dati sensibili nei cookie poiché potrebbero essere manipolati da utenti malintenzionati. Per memorizzare in modo sicuro dati sensibili durante la navigazione utente è necessario utilizzare le sessioni.

In PHP possiamo creare un cookie tramite la funzione setcookie(), la cui sintassi è la seguente:

setcookie(string $name, string $value = "", int $expire = 0, string $path = "", string $domain = "", bool $secure = false, bool $httpOnly = false);

e dove:

  • $name è il nome del cookie. Deve essere di tipo stringa ed è l'unico parametro obbligatorio, i successivi sono opzionali.
  • $value è il valore del cookie. Deve essere di tipo stringa.
  • $expire è la data di scadenza nel formato Unix timestamp. Trascorso tale tempo i cookie saranno inaccessibili. Il valore di default è 0.
  • $path specifica il percorso in cui il cookie sarà disponibile. Se impostato su /, il cookie sarà disponibile all'interno dell'intero dominio.
  • $domain specifica il dominio in cui il cookie è disponibile, ad esempio www.dominio.it
  • $secure se impostato a 1, specifica che il cookie può essere inviato solo tramite HTTPS.
  • $httpOnly è la modalità che rende il cookie non accessibile via Javascript.

Facciamo un esempio reale

<?php

$expire = 30*24*60*60;
setcookie("lang", "it", time() + $expire);

Nell'esempio precedente abbiamo creato un cookie di nome lang con la funzione setcookie() e gli abbiamo assegnato il valore it.

Abbiamo quindi impostato la scadenza tramite la funzione nativa di PHP time(), che ritorna il tempo attuale in timestamp, a cui abbiamo aggiunto un numero di secondi equivalente a 1 mese di 30 giorni (30 giorni per 24 ore per 60 minuti per 60 secondi).

Nota: Essendo un header, il cookie deve essere impostato prima di qualsiasi output HTML (anche una riga vuota), altrimenti viene generato un avviso come il seguente **

Warning: Cannot modify header information - headers already sent by...

** solo se la direttiva output_buffering del php.ini è impostata a Off.

Una volta creato un cookie, questo sarà accessibile tramite la variabile superglobale $_COOKIE, che è di tipo array come $_GET e $_POST.

Prendendo spunto dall'esempio precedente possiamo scrivere così

<?php

if ($_COOKIE["lang"] == 'it') {
    header('Location: /it');
} elseif ($_COOKIE["lang"] == 'en') {
    header('Location: /en');
} else {
    header('Location: /');
}
exit; // termina l'esecuzione dello script

La funzione header() di PHP consente l'invio di intestazioni HTTP al browser. In questo caso abbiamo utilizzato l'intestazione Location, che consente di reindirizzare l'utente verso l'URL specificato dopo i due punti.

Nel caso di un utente che accede per la prima volta a un sito multilingua, sapremo a quale versione del sito reindirizzarlo alla visita successiva, tramite il cookie memorizzato nella variabile $_COOKIE["lang"].

Nota: è consigliabile utilizzare la funzione isset() prima di accedere al valore di un cookie. La funzione isset() verifica l'esistenza di una variabile e che non sia impostata a NULL.

Per modificare un cookie possiamo semplicemente sovrascrivere il vecchio valore con il nuovo tramite la funzione setcookie()

<?php
setcookie("lang", "it");
setcookie("lang", "en"); // Qui stiamo sovrascrivendo il valore del cookie di nome lang

Per eliminare un cookie è sufficiente impostare il suo valore a "" (stringa vuota), oppure a 0 o qualsiasi valore che PHP interpreta come false.

<?php
secookie('lang', '');

Per essere certi di eliminare il cookie, dobbiamo passare il parametro $expire con un valore che fa riferimento al passato, come mostrato di seguito

<?php
$expire = time() -3600; // impostiamo $expire a un'ora fa
secookie('lang', '', $time);

Ora che sappiamo cos'è un cookie e come utilizzarlo nelle nostre applicazioni web, nella prossima guida analizzeremo un'altra variabile globale di PHP: la variabile $_SESSION.