Sticky Session con Reverse Proxy in ambienti clusterizzati/bilanciati con Apache Nginx e Delphi

Gestione della Sticky Session in ambienti bilanciati con Reverse Proxy
In ambienti ad alta disponibilità e con più nodi applicativi, il reverse proxy agisce da bilanciatore tra backend server. In questi casi, è fondamentale gestire la sticky session (o session affinity) per mantenere l’utente sempre sullo stesso nodo durante la durata della sessione.
Perché serve la Sticky Session?
- Evita la perdita della sessione utente in ambienti senza sessioni centralizzate
- Garantisce coerenza dei dati (es. login, carrello, flussi guidati)
- Semplifica lo sviluppo quando non è usato uno store condiviso (es. Redis, DB)
- In casi estremi, può evitare la duplicazione della sessione, ad esempio quando due richieste molto ravvicinate arrivano su nodi diversi prima che il cookie di sessione venga ricevuto dal browser e incluso nella seconda richiesta
Approccio lato server
Ogni backend deve identificarsi con un route ID univoco (es. xs22001
) e includerlo nel cookie di sessione:
Set-Cookie: XSTORESESSION=abcdef123456.xs22001; Path=/; HttpOnly; SameSite=Lax
In Delphi, la logica potrebbe essere:
function GetRouteSuffix: string;
begin
Result := 'xs' + IntToStr(Settings.porta_http);
end;
procedure SetSessionCookie(Response: TWebResponse; SessionID, RouteSuffix: string);
begin
Response.SetCookieField(
'',
'XSTORESESSION',
SessionID + '.' + RouteSuffix,
'/',
Now + 1,
True, // Secure
True, // HttpOnly
'Lax' // SameSite
);
end;
SameSite: Lax vs Strict
Nel contesto della sticky session, l’attributo SameSite
del cookie è cruciale:
- SameSite=Lax: consente al cookie di essere inviato anche in caso di navigazione cross-site come un clic su un link proveniente da Google, email, o annunci pubblicitari. È la scelta consigliata per garantire che il cookie venga inviato anche alla prima visita.
- SameSite=Strict: il cookie viene inviato solo se la navigazione avviene all’interno dello stesso dominio. Questo aumenta la sicurezza, ma impedisce il corretto funzionamento della sticky session su primo accesso da fonti esterne.
Configurazione Apache
<Proxy "balancer://xstorecluster">
BalancerMember http://10.30.0.23:22001 route=xs22001
BalancerMember http://10.30.0.23:22002 route=xs22002
ProxySet stickysession=XSTORESESSION
</Proxy>
ProxyPass "/" "balancer://xstorecluster/"
ProxyPassReverse "/" "balancer://xstorecluster/"
Configurazione Nginx
upstream xstorecluster {
ip_hash;
server 10.30.0.23:22001;
server 10.30.0.23:22002;
}
server {
listen 443 ssl;
server_name tecnomodelcar.com;
location / {
proxy_pass http://xstorecluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Considerazioni finali
Quando si implementa sticky session, è importante assicurarsi che:
- Il cookie sia settato con suffisso coerente al route dichiarato nel proxy
- Il reverse proxy sia configurato per riconoscere e interpretare correttamente quel cookie
- I nodi non condividano sessione in modo implicito (es. tramite memoria locale non sincronizzata)
- L’attributo SameSite sia impostato correttamente per evitare perdita di sessione al primo accesso
Alternativa: sessioni centralizzate con Redis
Redis è un sistema di archiviazione in-memory open source, estremamente veloce, ideale per la gestione di dati temporanei come le sessioni utente.
In alternativa alla sticky session, è possibile centralizzare le sessioni in un’istanza Redis condivisa da tutti i backend:
- Tutti i nodi accedono allo stesso store per leggere e scrivere la sessione
- L’utente può cambiare nodo ad ogni richiesta senza perdere lo stato
- È necessario un ID di sessione persistente nel cookie
Vantaggi di Redis rispetto alla sticky session:
- Alta scalabilità e tolleranza ai guasti
- Nessuna dipendenza dal routing proxy
- Supporto a sessioni persistenti, scadenzate e condivise tra servizi diversi
Redis richiede però più infrastruttura e attenzione alla sicurezza, ma rappresenta la scelta ottimale in ambienti enterprise o microservizi complessi.
Autore: Ivan Revelli – Synaptica