lunedì 3 novembre 2025

Corso di PHP: 9 – Gestione Sessioni e Cookie

9 – Gestione Sessioni e Cookie

Obiettivo didattico

Capire la differenza tra sessioni e cookie, imparare a creare e gestire sessioni in PHP, usare cookie per persistenza lato client, e mettere in pratica il tutto con un esercizio: implementare un carrello e-commerce semplificato.


1) Differenza tra sessioni e cookie — concetto chiave

  • Cookie

    • Piccoli file (coppie chiave/valore) memorizzati dal browser sul computer dell’utente.

    • Sono inviati automaticamente al server ad ogni richiesta verso il dominio che li ha impostati.

    • Sono utili per persistenza lato client: preferenze tema, tracking, ricordami.

    • Limitazioni: dimensione limitata (~4 KB per cookie, limite totale per dominio variabile), visibili al client (quindi sensibili al furto/modifica se non protetti).

  • Sessione

    • Dati memorizzati sul server associati a un identificatore (session id) che il client porta con sé, solitamente tramite un cookie di sessione.

    • Il server mantiene lo stato (es. dati di login, carrello) e il client contiene solo l’ID.

    • Vantaggi: i dati effettivi non sono memorizzati nel browser, maggior sicurezza e possibilità di memorizzare strutture dati complesse.

    • Svantaggi: consumo di risorse server, necessità di gestione della scadenza e di storage scalabile in ambienti distribuiti.

Sintesi: cookie = memoria lato client, sessione = memoria lato server + riferimento lato client.


2) Come funziona una sessione (flusso operativo)

  1. Il server crea una sessione quando necessario e genera un identificatore unico (session id).

  2. Al client viene inviato (di solito) un cookie contenente il session id.

  3. Ad ogni richiesta successiva il browser invia quel cookie; il server usa il session id per recuperare i dati della sessione (array, oggetti, ecc.).

  4. Quando l’utente effettua il logout o la sessione scade, il server distrugge i dati associati a quell’id.

Elementi pratici da conoscere:

  • session_start() (o equivalente) apre/ristabilisce la sessione.

  • Recupero/assegnazione: la sessione è generalmente rappresentata da un array associativo lato server (es. $_SESSION).

  • Terminazione: si devono fornire funzioni per distruggere la sessione in modo sicuro (session_unset() + session_destroy() e rimozione cookie di sessione).


3) Cookie: parametri importanti e considerazioni di sicurezza

Quando si imposta un cookie bisogna considerare:

  • nome e valore (entità chiave/valore).

  • durata (expire): tempo dopo il quale il cookie viene eliminato (session cookie = scade alla chiusura del browser).

  • path e domain: limitano dove il cookie è valido.

  • secure: se impostato, il cookie viene inviato solo tramite connessioni HTTPS.

  • HttpOnly: se impostato, il cookie non è accessibile via script JavaScript (riduce rischio XSS).

  • SameSite: controlla l’invio del cookie in contesti cross-site (Lax, Strict, None + Secure).

Buone pratiche:

  • Non mettere dati sensibili non cifrati nei cookie. Se devi memorizzare info sensibili, usa cookie come token che fa riferimento a dati server-side.

  • Impostare HttpOnly e Secure quando possibile.

  • Usare SameSite per mitigare CSRF (Cross-Site Request Forgery).


4) Gestione sicura delle sessioni

Rischi principali:

  • Session fixation: un attaccante fornisce un session id noto alla vittima e poi sfrutta la sessione autenticata.
    Mitigazione: rigenerare il session id dopo login (es. session_regenerate_id(true)).

  • Session hijacking: furto del session id (es. via XSS o rete non cifrata).
    Mitigazione: usare HTTPS, cookie HttpOnly, limitare durata sessione, associare sessione a IP o user agent con attenzione (può causare falsi positivi).

  • Scadenza e pulizia: definire timeout di inattività e rimuovere dati obsoleti.

  • Storage lato server: sessioni per siti con più server richiedono storage condiviso (file system condiviso, database, Redis/Memcached). Evitare dipendere solo dal file system locale in cluster.

Best practice operative:

  • Chiamare sempre la funzione di avvio della sessione in testa alla pagina prima di qualsiasi output.

  • Rigenerare l’id dopo l’autenticazione e in situazioni sensibili.

  • Limitare lo scope e la durata della sessione.

  • Distruggere la sessione al logout e cancellare il cookie di sessione.


5) Struttura dati tipica in sessione (esempi concettuali)

Esempi di come si possono organizzare i dati lato sessione (concetto, non codice):

  • Utente loggato:

    • session['user'] = { id: 42, username: 'mario', roles: ['user'] }

    • session['last_activity'] = 2025-09-21T11:00:00Z

  • Carrello (esempio):

    • session['cart'] = { product_id => { qty: 2, price: 9.90 }, ... }

    • Totali calcolati al volo dal server leggendo session['cart'].

  • Token CSRF:

    • session['csrf_token'] = 'random-string' per verificare i POST provenienti dal form.


6) Esempio concettuale: ciclo di vita di un carrello semplificato

Flusso utente:

  1. Utente visita sito — il server avvia/chiama la sessione.

  2. Quando l’utente aggiunge un prodotto al carrello, il server aggiorna session['cart'] (incrementa quantità, aggiunge prodotto).

  3. Nel checkout, il server calcola totali, imposte, spedizione leggendo la sessione; dopo pagamento finale, si può svuotare la sessione o mantenerne una parte per storico.

  4. Se l’utente non è loggato, la sessione tiene lo stato del carrello. Se successivamente effettua il login, si può fondere il carrello della sessione con quello salvato nel DB (merge).

Esempio di struttura (valori d’esempio):

  • session['cart'] = { 101: { name: "T-shirt", qty: 2, price: 15.00 }, 204: { name: "Cappello", qty: 1, price: 12.50 } }

  • Totale calcolato: (2 * 15.00) + (1 * 12.50) = 42.50


7) Esercizio svolto: carrello e-commerce semplificato (concettuale, passo-passo)

Obiettivo: descrivere la logica completa senza mescolare codice, così da poterla implementare facilmente.

Requisiti funzionali

  • Aggiungere prodotto al carrello.

  • Rimuovere prodotto o decrementare quantità.

  • Visualizzare il carrello con voci, quantità e subtotali.

  • Svuotare il carrello al completamento dell’ordine.

  • Conservare il carrello tra le pagine usando sessione.

Struttura dati (lato sessione)

  • session['cart'] mappa product_id → oggetto { qty, unit_price, name }.

Operazioni (algoritmo)

  1. Aggiungi prodotto

    • Ricevo product_id, qty (default 1).

    • Se product_id già presente in session['cart'], incremento qty.

    • Altrimenti aggiungo nuova voce con qty e unit_price preso dal catalogo.

    • Aggiorno session['last_update'] = now.

  2. Rimuovi prodotto

    • Ricevo product_id.

    • Se presente in session['cart'] rimuovo la voce o decremento la qty se richiesto.

  3. Visualizza carrello

    • Itero su session['cart'], calcolo subtotal per voce = qty * unit_price.

    • Sommo i subtotali per ottenere cart_total.

    • Mostro cart_total, numero di articoli (somma delle quantità) e dettagli delle voci.

  4. Checkout

    • Verifico che il carrello non sia vuoto.

    • Applico controlli (disponibilità, prezzi correnti, sconti).

    • Se tutto ok, creo l’ordine nel database e svuoto il carrello in sessione (oppure lo salvo nello storico dell’utente).

Esempio numerico (simulazione)

  • Azione: aggiungi product_id = 101 (T-shirt, unit_price = 15.00), qty = 2.

    • session['cart'] diventa {101: {qty:2, unit_price:15.00, name:"T-shirt"}}.

  • Azione: aggiungi product_id = 204 (Cappello, unit_price = 12.50), qty = 1.

    • session['cart'] ora contiene 2 voci.

  • Visualizza carrello:

    • Voce 101: subtotal = 2 * 15.00 = 30.00

    • Voce 204: subtotal = 1 * 12.50 = 12.50

    • Totale carrello = 42.50

Considerazioni pratiche

  • Sempre ricalcolare i prezzi dal catalogo al momento del checkout (evitare di fidarsi solo del valore in sessione).

  • Usare token CSRF per proteggere azioni POST (aggiungi/rimuovi).

  • Consentire agli utenti autenticati di salvare il carrello nel database per ripristino futuro su altri device.


8) Errori comuni e debugging

  • Sessione non inizializzata: chiamare la funzione di avvio della sessione prima di leggere/scrivere dati.

  • Output prima della session_start(): l’invio di output prima della definizione dei cookie o dell’avvio della sessione impedisce la corretta impostazione del cookie di sessione (headers already sent).

  • Dimenticare di rigenerare l’ID dopo il login → rischio session fixation.

  • Non chiudere / non distruggere la sessione al logout → rischio che una macchina condivisa mantenga una sessione attiva.

  • Dipendenza dallo storage locale su cluster → sessioni non condivise tra nodi (usare storage condiviso come Redis).

Per debug:

  • Loggare session_id() e il contenuto di session (in ambiente di sviluppo) per verificare flusso stato.

  • Verificare cookie nel browser (devtools → Application / Storage) per controllare scadenze e flag.


9) Domande di verifica rapida

  1. Qual è la differenza fondamentale tra cookie e sessione?
    Risposta: cookie = dati memorizzati nel browser (lato client); sessione = dati memorizzati sul server associati a un session id trasportato dal client.

  2. Perché rigenerare l’id di sessione dopo il login?
    Risposta: per mitigare session fixation; garantire che un id precedente non utilizzabile dall’attaccante rimanga valido dopo autenticazione.

  3. Quali flag di cookie aumentano la sicurezza?
    Risposta: HttpOnly, Secure, e SameSite (insieme aiutano a ridurre i rischi XSS/CSRF e furto su connessioni non TLS).

  4. Dove conviene memorizzare sessioni in un ambiente con più server?
    Risposta: in uno storage condiviso (Redis, Memcached, DB o filesystem condiviso) per rendere le sessioni accessibili da tutti i nodi.


10) Estensioni e miglioramenti pratici

  • Persistenza cross-device: salvare carrelli di utenti autenticati nel DB e fare merge con quello in sessione.

  • Utilizzare JWT (JSON Web Token) per autenticazione stateless quando appropriato (diverso modello rispetto a sessioni server-side).

  • Implementare limitazione della durata della sessione e logout automatico per inattività.

  • Monitorare e invalidare sessioni sospette (es. cambio IP frequente o attività anomale).


Nessun commento:

Posta un commento

Corso Fondamenti di Informatica e Reti: 6 Reti di computer e Internet

Reti di computer e Internet Introduzione Prova a pensare alla vita quotidiana senza reti informatiche: niente messaggi WhatsApp, niente m...