Autenticazione con JWT

Questo articolo esplora l’uso di JSON Web Token (JWT) per autenticare servizi RESTful. Tratteremo i principi, i vantaggi e gli svantaggi di JWT, con esempi pratici in PHP.

Prerequisiti

Si richiede familiarità con l’architettura RESTful, e basi di programmazione in PHP.

Introduzione

Il bisogno di limitare l’accesso a risorse specifiche agli utenti autenticati è comune sia per applicazioni web che API. JWT offre una soluzione sicura, stateless e scalabile, rispettando i principi RESTful.

Cos’è un JSON Web Token?

Un JWT è una stringa codificata che contiene tre sezioni principali:

  • Header: Contiene il tipo di token (JWT) e l’algoritmo di firma (ad esempio, HMAC-SHA256).
  • Payload: Include i claims, ovvero informazioni sull’utente come ID, ruoli e scadenza del token.
  • Signature: Una firma generata utilizzando una chiave segreta per garantire integrità e autenticità.

Esempio di JWT


        eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsInJvbGVzIjpbIlJPTEVfQURNSU4iLCJST0xFX1VTRVIiXSwiaWF0IjoxNjgwODg4MDAsImV4cCI6MTY4MDg5MTYwfQ.s6EoZQc9m3VfRu77E3J9PqjD5Ikg1N8d0Ilx_EBzYYQ
        

Autenticazione Stateless

In ambienti RESTful come micorservizi ed api delle applicazioni SPA, il server non mantiene stato tra richieste successive. JWT permette al client di inviare tutte le informazioni relative all’utente autenticato per ogni richiesta, evitando la gestione di sessioni lato server.

Vantaggi di JWT

  • Scalabilità: Riduce il carico sul server.
  • Efficienza: Le informazioni sono incluse nel token stesso.
  • Sicurezza: La firma garantisce che i dati non siano stati alterati.

Svantaggi di JWT

  • Compromissione della chiave: Se la chiave privata sul server con cui sono firmati i token viene scoperta, l’intero sistema è vulnerabile.
  • Revoca complessa: Non è possibile invalidare i token senza una blacklist.
  • Lunghezza del token: Può aumentare il carico di rete.

Implementazione in PHP

Generazione di un Token


        require 'vendor/autoload.php';

        use Firebase\JWT\JWT;

        $key = "your_secret_key";
        $payload = [
            "iss" => "example.com",
            "aud" => "example.com",
            "iat" => time(),
            "exp" => time() + 3600,
            "user_id" => 12345,
            "roles" => ["ROLE_ADMIN"]
        ];

        $jwt = JWT::encode($payload, $key, 'HS256');
        echo $jwt;
        

Validazione di un Token


        require 'vendor/autoload.php';

        use Firebase\JWT\JWT;
        use Firebase\JWT\Key;

        preg_match('/Bearer\s(\S+)/', $headers['Authorization'], $matches));
        $jwt = $matches[1];
        $key = file_get_contents('privateKey.pem');

        try {
            $decoded = JWT::decode($jwt, new Key($key, 'HS256'));
            print_r($decoded);
        } catch (Exception $e) {
            echo 'Token non valido: ', $e->getMessage();
        }
        
diagramma di sequenza uml jwt autenticazione
diagramma di sequenza uml jwt autenticazione

Riferimenti

Autenticazione Utente con le Sessioni

Introduzione

In un’applicazione web tradizionale, l’autenticazione degli utenti si basa sul meccanismo di sessione tra il server e il client, ovvero uno spazio di memoria a cui accede il server, spazio di memoria associato al client.
Il collegamento logico / il filo conduttore tra la sequenza di transazioni è l “id di sessione” generato dal webserver, memorizzato nei cookie del browser, ed inviato dal client nei cookies ad ogni richiesta.

Questo articolo analizza i passaggi principali di: login, verifica dello stato autenticato e logout. La descrizione è accompagnata da esempi di codice PHP.

Concetti chiave

Autenticazione: è il processo di controllo delle credenziali utente (username/password). L’autenticazione dell’utente ha successo se viene trovata una corrispondenza tra le credenziali inserite in fase di login con i dati salvati in fase di registrazione.

Autorizzazione: è il controllo dei diritti dell’utente di accedere a determinate risorse.

1. Login

Durante la fase di login, l’utente inserisce le proprie credenziali (nome utente e password) in un form HTML. Il server valida queste credenziali e, in caso di successo, avvia una sessione. Ecco i passaggi principali:

  1. Invio delle credenziali: Le credenziali vengono inviate al server tramite una richiesta HTTP POST.
  2. Validazione delle credenziali: Il server verifica le credenziali confrontandole con i dati memorizzati (es. in un database).
  3. Avvio della sessione: In caso di successo, il server avvia una sessione utilizzando session_start() e memorizza informazioni sull’utente autenticato nella superglobale $_SESSION.
<?php
// Pseudocodice per il login
session_start();

// Validazione delle credenziali
$username = $_POST['username'];
$password = $_POST['password'];

if (validate_credentials($username, $password)) {
    $_SESSION['user'] = [
        'id' => get_user_id($username),
        'username' => $username
    ];
    header('Location: dashboard.php');
    exit;
} else {
    echo 'Credenziali non valide.';
}
?>

2. Verifica dello Stato Autenticato

Ad ogni richiesta HTTP, il server verifica se l’utente è autenticato controllando i dati nella sessione. Questo processo garantisce che solo gli utenti autenticati possano accedere a risorse protette.

<?php
// Pseudocodice per proteggere una pagina
session_start();

if (!isset($_SESSION['user'])) {
    // Reindirizza l'utente alla pagina di login
    header('Location: login.php');
    exit;
}

// L'utente è autenticato, procedi con la logica della pagina
echo 'Benvenuto, ' . htmlspecialchars($_SESSION['user']['username']);
?>

Diagramma uml di sequenza
Diagramma uml di sequenza

3. Logout

Il logout termina la sessione dell’utente eliminando i dati memorizzati e distruggendo l’ID di sessione. Questo passaggio previene ulteriori accessi senza una nuova autenticazione.

<?php
// Pseudocodice per il logout
session_start();

// Elimina i dati della sessione
$_SESSION = [];

// Distrugge la sessione
session_destroy();

// Reindirizza alla pagina di login
header('Location: login.php');
exit;
?>

Considerazioni sulla Sicurezza

  • Abilita session.cookie_secure per trasmettere i cookie solo su connessioni HTTPS.
  • Usa session_regenerate_id() dopo il login per prevenire attacchi di session fixation.
  • Configura session.cookie_httponly per evitare accessi JavaScript ai cookie.

Le sessioni in PHP

Cosa Sono le Sessioni PHP?

Le sessioni PHP forniscono un modo per memorizzare informazioni tra più richieste in un’applicazione web.
In altri termini le sessioni PHP rendono Stateful una successione di connessioni HTTP che è un protocollo di comunicazione per sua natura Stateless. Una applicazione / protocollo di comunicazione è stateless (senza stato) quando non salva i dati generati in una sessione / connessione per utilizzarli nel corso di quelle successive. Una applicazione / protocollo di comunicazione è stateful quando conserva i dati generati in una sessione / connessione per utilizzarli nel corso di quelle successive.

I dati di sessione in PHP di default vengono memorizzati lato server, e al fine di mantenere un legame / un file conduttore nella sequenza di transazioni HTTP. Solo un ID di sessione viene condiviso con il client, tipicamente tramite un cookie o piu raramente con un parametro URL.

Come Funzionano le Sessioni PHP

  1. Quando una sessione inizia, PHP genera un ID di sessione univoco.
  2. L’ID di sessione viene inviato al client, in un cookie chiamato di default PHPSESSID.
  3. di default PHP memorizza i dati di sessione lato server in un file con il nome dell’ID di sessione, a meno che non venga usato un altro meccanismo di archiviazione. Di conseguenza quando la session inizia PHP crea il file di sessione.
  4. Alle richieste successive, il client invia l’ID di sessione al server, consentendo a PHP di recuperare i dati della sessione.

Uso Base delle Sessioni PHP

<?php
// Avvia la sessione
session_start();

// Memorizza un valore nella sessione
$_SESSION['username'] = 'JohnDoe';

// Recupera e visualizza il valore
if (isset($_SESSION['username'])) {
    echo 'Ciao, ' . $_SESSION['username'];
}

// Distrugge la sessione
session_destroy();
?>

la funzione session_start() di php

La funzione session_start() di PHP avvia una nuova sessione o riprende una sessione esistente per l’utente corrente. È una funzione fondamentale per gestire le sessioni nel contesto delle applicazioni web.

Funzionamento

  1. Inizializza o riprende una sessione: Se non esiste già una sessione, session_start() ne crea una nuova e genera un identificativo univoco di sessione (session ID). Se invece esiste una sessione attiva per l’utente (identificata da un cookie o tramite URL), PHP riprende quella sessione.
  2. Gestione dell’identificativo di sessione (Session ID):
    • Quando si avvia una nuova sessione, PHP genera un identificativo unico (ad esempio abc123) che viene utilizzato per identificare i dati della sessione associati a quell’utente.
    • L’ID della sessione viene inviato al client tramite un cookie (di default chiamato PHPSESSID).
  3. Associazione a dati utente: Dopo aver avviato una sessione, PHP utilizza l’ID della sessione per associare i dati dell’utente ad un array superglobale chiamato $_SESSION.

Esempio di utilizzo

php

// Avvia o riprende una sessione
session_start();
// Aggiunge un valore alla sessione
$_SESSION['username'] = 'utente123';
$_SESSION['role'] = 'admin';
// Recupera i dati della sessione
echo 'Benvenuto, ' . $_SESSION['username']; // Output: Benvenuto, utente123
?>

Dettagli tecnici

  • Archiviazione dei dati di sessione: I dati di sessione sono memorizzati sul server, di default nel filesystem (in una directory come /tmp), e il browser conserva solo l’ID della sessione.
  • Cookie di sessione: Quando viene chiamata session_start(), PHP invia un cookie al client con il nome predefinito PHPSESSID che contiene l’ID della sessione.

    Esempio di intestazione HTTP inviata al client:

    http
    Copia codice
    Set-Cookie: PHPSESSID=abc123; path=/; HttpOnly
  • Ripristino di una sessione esistente: Se il browser invia il cookie con l’ID della sessione, session_start() recupera i dati associati a quell’ID.

Quando usare session_start()

  1. Prima di accedere a $_SESSION: Deve essere sempre chiamata prima di leggere o scrivere dati nell’array $_SESSION.
  2. All’inizio di uno script: Per garantire che la sessione sia inizializzata correttamente prima di accedere ai dati dell’utente.

Esempio errato (causerà un errore):


<?php
$_SESSION['username'] = 'utente123'; // Errore: session_start() non è stato chiamato
?>

Esempio corretto:


<?php
session_start(); // Avvia la sessione
$_SESSION['username'] = 'utente123'; // Ora funziona correttamente
?>

Errori comuni

  1. Sessione già avviata: Se session_start() viene chiamata dopo che l’intestazione HTTP è già stata inviata, genera un errore. Errore tipico:
    css
    Copia codice
    Warning: session_start(): Cannot send session cookie - headers already sent

    Soluzione: Assicurarsi che session_start() sia chiamata all’inizio dello script, prima di qualsiasi output.

  2. Conflitto di sessioni: Utilizzare un nome specifico per la sessione con session_name() per evitare conflitti in applicazioni condivise.

Parametri opzionali

A partire da PHP 7.0, session_start() accetta un array opzionale di opzioni:


session_start([
    
'cookie_lifetime' => 3600, // Durata del cookie in secondi
    
'read_and_close' => true,  // Chiude la sessione subito dopo la lettura
]);

In sintesi la funzione session_start():

  • Crea una nuova sessione o riprende una esistente.
  • Gestisce l’identificativo di sessione (Session ID).
  • Permette di associare dati persistenti all’utente attraverso l’array superglobale $_SESSION.

Opzioni di Configurazione di PHP per le sessioni

Le sessioni PHP sono configurabili tramite il file php.ini o ini_set(). Ecco alcune opzioni comuni:

  • session.save_path: Percorso in cui sono memorizzati i file di sessione.
  • session.gc_maxlifetime: Durata massima dei dati di sessione in secondi.
  • session.cookie_secure: Garantisce che i cookie vengano inviati solo tramite HTTPS.
  • session.use_strict_mode: Impone una gestione rigorosa degli ID di sessione per migliorare la sicurezza.

PHP offre diverse configurazioni relative alla gestione delle sessioni, tutte personalizzabili tramite il file php.ini, direttive ini_set() o configurazioni specifiche in runtime. Di seguito sono descritte le principali impostazioni per la gestione delle sessioni.

1. session.save_path

Specifica la directory in cui vengono salvati i file di sessione lato server (ad esempio, file temporanei contenenti i dati delle sessioni).

  • Valore predefinito: Sistema operativo specifico, ad esempio /tmp su Linux.
  • Esempio:
    
    session.save_path = "/var/lib/php/sessions"

2. session.name

Specifica il nome del cookie che contiene l’ID della sessione. Il valore predefinito è PHPSESSID.

  • Esempio:
    
    session.name = "MYSESSIONID"

3. session.gc_maxlifetime

Determina il tempo (in secondi) dopo il quale i dati di sessione inutilizzati vengono eliminati dal server durante il garbage collection.

  • Valore predefinito: 1440 (24 minuti).
  • Esempio:
    
    session.gc_maxlifetime = 3600

4. session.gc_probability e session.gc_divisor

Definiscono la probabilità che il garbage collection delle sessioni venga eseguito.

  • Formula: gc_probability / gc_divisor determina la probabilità di esecuzione.
  • Valore predefinito: 1 (probabilità) su 100 (divisore), cioè 1%.
  • Esempio:
    
    session.gc_probability = 1
    session.gc_divisor = 100

5. session.cookie_lifetime

Imposta la durata del cookie di sessione sul client (browser). Se è 0, il cookie scade quando il browser viene chiuso.

  • Valore predefinito: 0.
  • Esempio:
    
    session.cookie_lifetime = 86400  ; 24 ore

6. session.cookie_path

Specifica il percorso in cui il cookie di sessione è valido sul dominio.

  • Valore predefinito: / (valido per tutto il sito).
  • Esempio:
    
    session.cookie_path = "/"

7. session.cookie_domain

Definisce il dominio per cui il cookie di sessione è valido.

  • Valore predefinito: Vuoto (cookie valido solo per il dominio corrente).
  • Esempio:
    
    session.cookie_domain = "example.com"

8. session.cookie_secure

Imposta se il cookie di sessione deve essere trasmesso solo su connessioni HTTPS.

  • Valore predefinito: Off.
  • Esempio:
    
    session.cookie_secure = On

9. session.cookie_httponly

Impedisce l’accesso al cookie di sessione tramite JavaScript (protezione contro attacchi XSS).

  • Valore predefinito: Off.
  • Esempio:
    
    session.cookie_httponly = On

10. session.use_cookies

Determina se PHP utilizza i cookie per memorizzare l’ID della sessione.

  • Valore predefinito: 1 (Attivo).
  • Esempio:
    
    session.use_cookies = 1

11. session.use_only_cookies

Forza PHP a utilizzare solo cookie per l’ID di sessione, disabilitando il passaggio di ID tramite URL (per evitare attacchi session fixation).

  • Valore predefinito: 1 (Attivo).
  • Esempio:
    
    session.use_only_cookies = 1

12. session.use_trans_sid

Permette di aggiungere automaticamente l’ID della sessione agli URL, se i cookie sono disabilitati. Questa impostazione è deprecata per motivi di sicurezza.

  • Valore predefinito: 0 (Disabilitato).
  • Esempio:
    
    session.use_trans_sid = 0

13. session.sid_length

Specifica la lunghezza del session ID (da 22 a 256 caratteri).

  • Valore predefinito: 32.
  • Esempio:
    
    session.sid_length = 48

14. session.sid_bits_per_character

Definisce il numero di bit usati per ogni carattere nel session ID (da 4 a 6).

  • Valore predefinito: 4.
  • Esempio:
    
    session.sid_bits_per_character = 6

Modifica delle configurazioni a runtime

È possibile modificare alcune delle configurazioni di sessione direttamente nello script PHP usando la funzione ini_set().

Esempio:


<?php
ini_set('session.gc_maxlifetime', 3600); // Sessione valida per 1 ora
ini_set('session.cookie_secure', 1);     // Forza HTTPS
ini_set('session.cookie_httponly', 1);   // Blocca accesso JavaScript ai cookie
session_start();
?>

Controllo delle configurazioni correnti

Puoi visualizzare le impostazioni attuali relative alle sessioni utilizzando la funzione phpinfo() o ini_get().

Esempio:


<?php
echo ini_get('session.gc_maxlifetime'); // Visualizza il valore attuale
phpinfo(); // Mostra tutte le configurazioni correnti
?>

Come funziona la gestione delle sessioni nel web server integrato

  1. Gestione standard:
    • Il server incorporato rispetta le impostazioni di sessione definite nel file php.ini o quelle modificate tramite ini_set() nello script.
    • I file di sessione vengono salvati nella directory specificata da session.save_path.
  2. Persistenza delle sessioni:
    • Le sessioni vengono mantenute tra le richieste HTTP, a patto che il server sia in esecuzione e il client invii il cookie con l’ID di sessione (ad esempio, il cookie PHPSESSID).
  3. Nessuna configurazione aggiuntiva:
    • Il built-in server di PHP è progettato per eseguire applicazioni PHP in modo semplice e gestisce automaticamente le funzionalità di base come le sessioni.

Esempio di utilizzo delle sessioni con il built-in server

Script PHP con gestione della sessione

Crea un file chiamato session_example.php:


<?php
// Avvia la sessione
session_start();
// Incrementa un contatore nella sessione
if (isset($_SESSION['counter'])) {
    
$_SESSION['counter']++;
} else {
    
$_SESSION['counter'] = 1;
}
// Mostra il contatore
echo "Hai visitato questa pagina {$_SESSION['counter']} volte.";
// Link per resettare la sessione
echo '<br><a href="session_example.php?reset=true">Resetta sessione</a>';
// Gestisce il reset della sessione
if (isset($_GET['reset']) && $_GET['reset'] === 'true') {
    
session_destroy();
    
echo '<br>Sessione resettata.';
}
?>

Avvia il web server integrato

Esegui il server nella directory in cui si trova il file:


php -S localhost:8000

Poi visita l’indirizzo: http://localhost:8000/session_example.php.

  • Ogni volta che ricarichi la pagina, il contatore ($_SESSION['counter']) aumenta.
  • Quando clicchi sul link “Resetta sessione”, la sessione viene distrutta.

Limitazioni del PHP Built-in Web Server

  1. Uso per sviluppo:
    • Il web server integrato è progettato esclusivamente per lo sviluppo e il testing, non per ambienti di produzione. Non è ottimizzato per gestire molte richieste simultanee o per garantire la sicurezza necessaria in produzione.
  2. Garbage collection delle sessioni:
    • Il built-in server si comporta come gli altri ambienti PHP per il garbage collection delle sessioni, basandosi sulle configurazioni di session.gc_probability e session.gc_divisor.
  3. Concorrenza:
    • Se hai più richieste concorrenti (ad esempio tramite AJAX), la gestione della sessione può causare blocchi temporanei poiché PHP blocca il file di sessione fino a quando la richiesta corrente non è terminata.

Dove vengono salvati i file di sessione?

Con la configurazione di default i file di sessione vengono salvati nella directory specificata dalla direttiva session.save_path. Se non è configurata, PHP utilizza la directory predefinita del sistema (ad esempio, /tmp su Unix/Linux).

Puoi verificare la directory con il seguente codice:


<?php
echo session_save_path();
?>

Gestori Personalizzati di Sessione

PHP consente agli sviluppatori di definire gestori personalizzati per memorizzare i dati di sessione in archivi alternativi come database o cookie.

Atri metodi di memorizzare le sessioni: le sessioni salvate in cookie criptati,  le sessioni salvate su database

PHP Core è in grado di gestire metodi alternativi per memorizzare le sessioni, come salvarle in cookie criptati o in un database, senza bisogno di librerie esterne. Tuttavia, ciò richiede la personalizzazione delle funzionalità di gestione delle sessioni fornite da PHP, utilizzando le funzioni integrate per modificare il comportamento predefinito.


1. Gestione delle sessioni in cookie criptati

PHP permette di gestire le sessioni salvandole direttamente nei cookie del browser anziché nel filesystem del server. Per farlo, puoi usare il gestore di sessione personalizzato tramite la funzione session_set_save_handler().

Esempio di sessioni salvate nei cookie criptati


<?php
session_set_save_handler(
    
'open',
    
'close',
    
'read',
    
'write',
    
'destroy',
    
'gc'
);
// Funzione per criptare i dati
function encrypt_data($data) {
    
$key = 'my-secret-key'; // Usa una chiave sicura
    
return base64_encode(openssl_encrypt($data, 'aes-256-cbc', $key, 0, str_repeat('0', 16)));
}
// Funzione per decriptare i dati
function decrypt_data($data) {
    
$key = 'my-secret-key';
    
return openssl_decrypt(base64_decode($data), 'aes-256-cbc', $key, 0, str_repeat('0', 16));
}
// Funzione per leggere la sessione
function read($session_id) {
    
if (isset($_COOKIE[$session_id])) {
        
return decrypt_data($_COOKIE[$session_id]);
    
}
    
return '';
}
// Funzione per scrivere nella sessione
function write($session_id, $data) {
    
$encrypted_data = encrypt_data($data);
    
setcookie($session_id, $encrypted_data, time() + 3600, "/");
    
return true;
}
// Altre funzioni richieste (open, close, destroy, gc)
function open() {
    
return true;
}
function close() {
    
return true;
}
function destroy($session_id) {
    
setcookie($session_id, '', time() - 3600, "/");
    
return true;
}
function gc($maxlifetime) {
    
return true; // Nessuna gestione necessaria per i cookie
}
// Avvio della sessione
session_start();
$_SESSION['username'] = 'utente123';
echo 'Benvenuto, ' . $_SESSION['username'];
?>

Cosa fa il codice:

  • I dati di sessione vengono salvati nel cookie del browser, criptati con AES-256.
  • I cookie sono sicuri e non leggibili dall’utente.
  • Non è richiesto l’uso di file lato server per memorizzare le sessioni.

2. Gestione delle sessioni salvate in un database

Anche per memorizzare le sessioni in un database, puoi utilizzare session_set_save_handler() per definire un gestore di sessioni personalizzato. In questo caso, i dati di sessione sono salvati in una tabella del database.

Esempio di sessioni salvate su database

Tabella MySQL per memorizzare le sessioni:


CREATE TABLE sessions (
    
session_id VARCHAR(255) NOT NULL PRIMARY KEY,
    
session_data TEXT NOT NULL,
    
session_expiry INT NOT NULL
);

Script PHP per gestire le sessioni:


<?php
session_set_save_handler(
    
'open',
    
'close',
    
'read',
    
'write',
    
'destroy',
    
'gc'
);
function open() {
    
$GLOBALS['db'] = new PDO('mysql:host=localhost;dbname=test', 'root', '');
    
return true;
}
function close() {
    
$GLOBALS['db'] = null;
    
return true;
}
function read($session_id) {
    
$stmt = $GLOBALS['db']->prepare('SELECT session_data FROM sessions WHERE session_id = :session_id AND session_expiry > :time');
    
$stmt->execute([
        
':session_id' => $session_id,
        
':time' => time()
    
]);
    
return $stmt->fetchColumn() ?: '';
}
function write($session_id, $data) {
    
$expiry = time() + ini_get('session.gc_maxlifetime');
    
$stmt = $GLOBALS['db']->prepare('REPLACE INTO sessions (session_id, session_data, session_expiry) VALUES (:session_id, :session_data, :session_expiry)');
    
return $stmt->execute([
        
':session_id' => $session_id,
        
':session_data' => $data,
        
':session_expiry' => $expiry
    
]);
}
function destroy($session_id) {
    
$stmt = $GLOBALS['db']->prepare('DELETE FROM sessions WHERE session_id = :session_id');
    
return $stmt->execute([':session_id' => $session_id]);
}
function gc($maxlifetime) {
    
$stmt = $GLOBALS['db']->prepare('DELETE FROM sessions WHERE session_expiry < :time');
    
return $stmt->execute([':time' => time()]);
}
// Avvio della sessione
session_start();
$_SESSION['username'] = 'utente123';
echo 'Benvenuto, ' . $_SESSION['username'];
?>

Cosa fa il codice:

  • Salva i dati di sessione in un database MySQL, PostgreSQL o simile.
  • Garantisce la persistenza dei dati anche in caso di riavvio del server PHP.

Considerazioni

  1. Cookie criptati:
    • Vantaggi: Nessuna necessità di archiviazione lato server.
    • Svantaggi: Dimensione limitata (max 4 KB) e possibili problemi di sincronizzazione in browser con politiche sui cookie.
  2. Database:
    • Vantaggi: Scalabilità, persistenza dei dati su più server e capacità di analisi delle sessioni.
    • Svantaggi: Maggiore complessità e potenziale overhead sul database.
  3. Implementazione nativa:
    • PHP fornisce tutti gli strumenti per gestire questi approcci senza librerie esterne.
    • L’uso di funzioni come session_set_save_handler() permette di personalizzare completamente il comportamento delle sessioni.

Scrittura dei dati in Sessione

La scrittura dei dati in sessione non avviene immediatamente quando valorizzi la variabile superglobale $_SESSION, ma al termine dello script, nel momento in cui PHP chiude la sessione e salva i dati.


Quando avviene la scrittura in sessione

  1. Quando modifichi $_SESSION durante l’esecuzione di uno script:
    
    $_SESSION['key'] = 'value';
    • Il dato viene aggiornato solo nella copia locale di $_SESSION, che risiede in memoria (RAM) mentre lo script è in esecuzione.
  2. Salvataggio dei dati:
    • PHP salva i dati di sessione nel percorso configurato (es. filesystem, database, ecc.) alla fine dello script, durante la fase di shutdown, dopo che tutte le operazioni sono state completate.
    • Questo avviene automaticamente grazie alla funzione session_write_close(), che PHP chiama implicitamente quando lo script termina, a meno che non venga chiamata manualmente prima.

Esempio per chiarire

Codice PHP:


<?php
session_start();
// Modifica il valore in $_SESSION
$_SESSION['username'] = 'utente123';
// Legge subito il valore modificato
echo "Username in sessione: " . $_SESSION['username'];
// Simula un'operazione manuale di salvataggio e chiusura
session_write_close(); 
// Prova a modificare la sessione dopo averla chiusa
$_SESSION['username'] = 'altro_utente';
?>
  1. Quando esegui:
    
    $_SESSION['username'] = 'utente123';
    • Il dato è aggiornato in $_SESSION (memoria locale).
  2. La sessione viene salvata in modo definitivo quando PHP chiama session_write_close() (o implicitamente al termine dello script).
  3. Se provi a modificare $_SESSION dopo aver chiuso la sessione con session_write_close(), le modifiche non saranno salvate, perché il salvataggio avviene solo fino al momento della chiusura.

Funzioni correlate

  1. session_write_close():
    • Forza il salvataggio dei dati di sessione e chiude la sessione, rendendo i dati disponibili ad altre richieste.
    • Esempio:
      
      session_write_close();
  2. session_abort():
    • Annulla le modifiche fatte a $_SESSION durante lo script, lasciando i dati della sessione invariati rispetto allo stato iniziale.
  3. Comportamento al termine dello script:
    • PHP chiama automaticamente session_write_close() alla fine dello script, garantendo che tutte le modifiche siano salvate.

Il dato in $_SESSION viene salvato in sessione (persistenza) al termine dello script o quando viene chiamata esplicitamente la funzione session_write_close(). La semplice assegnazione di un valore a $_SESSION aggiorna la variabile superglobale solo in memoria fino a quel momento.

Trappole Comuni e Best Practices

  • Chiama sempre session_start() prima di modificare $_SESSION.
  • Usa session_regenerate_id() per prevenire attacchi di session fixation.
  • Proteggi le tue sessioni abilitando session.cookie_secure e session.cookie_httponly.