Sebbene personalmente non ami particolarmente l'uso della sessione nelle web-application, spesso essa viene utilizzata anche perchè non si può fare altrimenti. La seconda affermazione (spesso viene utilizzata) spiega il perchè di questo post, difronte infatti ad un'applicazione che ne faceva un largo uso ho cercato di capirne il funzionamento nei suoi dettagli.
Partiamo dal fondo dalla sua definizione formale, la sessione così come la conosciamo è definita dall' HTTP State Management Mechanism RFC. Essa infatti:
This document specifies a way to create a stateful session with HTTP requests and responses.It describes two new headers, Cookie and Set-Cookie, which carry state information between participating origin servers and user agents. The method described here differs from Netscape's Cookie proposal,but it can interoperate with HTTP/1.0 user agents that use Netscape's method. (See the HISTORICAL section.)
Sostanzialmente per quello che riguarda ASP.NET senza addentrarci troppo nei dettagli della RFC 2109 vi riporto una semplice e sommaria descrizione di come le cose funzionano,
Il Server si occupa di generare una nuova sessione (se necessario), mantienere la sessione e l'elimina all'occorrenza.
Il Client si occupa di ricordare al Server quale è la sessione che lo riguarda.
Come si può notare la maggior parte del lavoro è portata avanti dal Server, il gioco è basato su di uno scambio costante, tra il Client ed il Server, di particolari Cookie (non sono come i classici cookie salvati nel hard-disk del client), il Server alla generazione della nuova sessione inserisce nella response un header in più, il Set-Cookie. Il Client per confermare al Server il mantenimento della sessione inserisce un header in più nella Request fatta, il Cookie. Il Set-Cookie viene conservato nella cache del Client (se sbaglio correggetemi :| ).
NB. Questa descrizione è una mia libera interpretazione per avere un quadro certo sul funzionamento della RFC basta leggersela.
Dopo questa breve descrizione vediamo in pratica come verificare i concetti espressi sin d'ora. Quello che ci serve è una Web-App che generi una nuova sessione :) e di un tool che effettui dello sniffing per verificare il contenuto delle Request e delle Response passate tra il Client ed il Server.
Partiamo dalla prima cosa, per questo apro Microsoft Visual Web Developer 2008 Expr. Ed. creo una nuova ASP.NET Web Application.
Default.aspx:
1: <%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="SessionTest._Default" %>
2:
3: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
4:
5: <html xmlns="http://www.w3.org/1999/xhtml" >
6: <head runat="server">
7: <title></title>
8: </head>
9: <body>
10: <form id="form1" runat="server">
11: <div>
12: <p>
13: <%Response.Write(Session.SessionID)% >
14: </p>
15: </div>
16: </form>
17: </body>
18: </html>
Default.aspx.vb:
1: Partial Public Class _Default
2: Inherits System.Web.UI.Page
3:
4: Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
5: Session("TestSession") = "Test Della Sessione"
6: End Sub
7:
8: End Class
Nel code-behind genero una nuova sessione con l'assegnazione al'oggetto Session("TestSession") un valore stringa qualsiasi vedi linea 4 del file Default.aspx.vb, nel file Default.aspx visualizzo l'ID della sessione appena generata nel Server. Per verificare lo scambio di Set-Cookie e Cookie tra Server e Client utilizziamo Firebug, abilito quindi il "Support For Network Monitoring", premiamo F5 nel Web Developer per attivare il debug. Quello che succede poi vine mostrato nell'immagine sotto:
Evidenziate in rosso l'Id della Sessione visualizzato nella pagina (primo in alto) ed il Set-Cookie nell Header (intestazione) della Response passato al Client dal Server (secondo riquadro in basso).
Ora per vedere l'Header Cookie Passato dal Client al Server basta effettuare un refresh della pagina:
In questo caso il secondo riquadro rosso nell'immagine sopra mostra l'Header Cookie aggiunto nella Request fatta dal Client al Server.
Tra i vari problemi legati a questo tipo di teconoliga possimao evidenziarne uno introdotto con l'utilizzo dei Tab nei moderni browser, se infatti aprissi un nuovo tab nell'istanza precedente di Firefox e navigassi fino alla stessa risorsa mi accorgerei che:
viene visualizzato lo stesso numero di sessione (riquadro rosso), di conseguenza in uno scenario complesso se effettuassi modifiche che hanno impatto nella sessione, nel tab in alto, poi nel tab che sta sotto mi troverei lo stato della sessione modificato (note l'immagine sopra è stata realizzata con l'utilizzo dell'add-on per Firefox Split Browser).
Conclusioni:
Queste anomalie non investono solo le applicazioni ASP.NET provate ad accedere a due Account di Gmail differenti su due tab differenti di Firefox o internet Explorer, nella stessa istanza del Browser, provate poi ad effettuare qualche modifica nei settings di un account e verificate cosa succede all'altro. Fino a poco tempo fa succedevano delle cose strane tipo email che invece di arrivare ad un account arrivano magicamente nell'altro account.