Cómo detectar si la sesión ha caducado en ASP.NET (Método II)

En mi anterior post comentaba brevemente el funcionamiento más común de los sistemas de sesiones de los servidores de aplicaciones Web y en particular el de ASP y ASP.NET. Éste lleva acarreados una serie de problemas cuando ls sesiones terminan por lo que comentaba una forma sencilla de detectar que una sesión había caducado. En dicho post comenté que iba a explicar una forma más “profesional” y autocontenida de comprobar si una sesión está activa o no en ASP.NET, y a eso voy…


El mecanismo para comprobar si la sesión actual está caducada o no pasa por el uso de una propiedad no muy conocida de la clase HttpContext: IsNewSession. Esta propiedad devuelve ‘verdadero’ únicamente cuando se acaba de crear una sesión para el usuario justo en la petición actual. Una sesión se crea cuando se crea una variable de sesión por primera vez. Al hacerlo se envía al cliente una cabecera con el identificador de sesión que es el que posteriormente el navegador envía de nuevo al servidor en cada petición, permitiendo así detectar a qué sesión pertenece dicha petición (suena más complicado de lo que es). Esta cabecera es realmente una cookie que sólo se mantiene activa mientras dura la sesion (cookie de sesión) ya que nunca se persiste a disco. La cookie se identifica con el nombre “ASP.NET_SessionId“.


El navegador no es consciente de si la sesión ha caducado o no en el servidor, por lo tanto sigue enviando todo el tiempo la cabecera sin saber si realmente vale para algo. El sistema de detección de la sesión caducada se basa en que, cuando la sesión caduca, en la siguiente petición que se haga al servidor se crea una nueva sesión. A diferencia de la primera vez en la que se crea la sesión, cuando ésta caduca ya existe la cebecera “ASP.NET_SessionId” en las peticiones del navegador. Por lo tanto una petición cuya sesión acaba de caducar es aquella en la que se crea una nueva sesión pero al mismo tiempo existe esta cabecera en la petición.


Puesto en forma de código esta condición se expresa de modo similar a este:

    public static bool IsSessionTimedOut()
{
HttpContext ctx = HttpContext.Current;
if (ctx == null)
throw new Exception(“Este método sólo se puede usar en una aplicación Web”);

//Comprobamos que haya sesión en primer lugar
//(por ejemplo si por ejemplo EnableSessionState=false)
if (ctx.Session == null)
return false; //Si no hay sesión, no puede caducar
//Se comprueba si se ha generado una nueva sesión en esta petición
if (!ctx.Session.IsNewSession)
return false; //Si no es una nueva sesión es que no ha caducado

HttpCookie objCookie = ctx.Request.Cookies[“ASP.NET_SessionId”];
//Esto en teoría es imposible que pase porque si hay una
//nueva sesión debería existir la cookie, pero lo compruebo porque
//IsNewSession puede dar True sin ser cierto (más en el post)
if (objCookie == null)
return false;

//Si hay un valor en la cookie es que hay un valor de sesión previo, pero como la sesión
//es nueva no debería estar, por lo que deducimos que la sesión anterior ha caducado
if (!string.IsNullOrEmpty(objCookie.Value))
return true;
else
return false;
}


He incluido comentarios para que sea más fácil seguir la lógica.


Como vemos lo primero que se hace es obtener una referencia al contexto actual de la petición Web (si no existe es que no estás usando este método en una petición Web). Lo siguiente que se hace es comprobar si hay sesión. No siempre existe ya que se puede desconectar la gestión de sesiones en la página o en toda la aplicación (a través de un ajuste en web.config). Luego es cuando viene lo que expliqué en el párrafo anterior: se comprueba si hay una nueva sesión con IsNewSession. Siendo así se obtiene una referencia a la cookie de sesión. Si no existe es que es la primera vez que se crea la sesión para este usuario, pero si existe y contiene algún valor es que existió una sesión anterior y por lo tanto, al estar creándola de nuevo, se había caducado.


He dejado este código en una clase llamada SessionTimeOut para que si tienes interés te la bajes directamente lista para usar.


En el próximo post comentaré casi lo contrario a esto: cómo conseguir que la sesión no caduque mientras el usuario tenga el navegador abierto, aunque no haga petición alguna en mucho rato y sin ampliar el tiempo de sesión ad infinitum, lo cual tiene muchas aplicaciones prácticas.

Sin categoría

9 thoughts on “Cómo detectar si la sesión ha caducado en ASP.NET (Método II)

  1. Jose, hace unos meses escribi este articulo (idem je)
    lo dejo aqui para que se relacionen… en esta comunidad Geeks.ms, junto a tus excelentes comentarios.

    La idea es la misma, solo que coloque en un MasterPage que luego herede, para que en cada “cierre del navegador” los usuarios se autentiquen nuevamente…

    – Detectar nueva session y obligar al usuario a logearse nuevamente
    http://geeks.ms/blogs/fernandezja/archive/2007/10/25/detectar-nueva-session-y-obligar-al-usuario-a-logearse-nuevamente.aspx

    Saludos.
    Jose A. Fernandez
    http://geeks.ms/blogs/fernandezja

  2. Hola a los dos:

    – Jorge: tienes razón: como lo que hago aquí es crossposting de mi blog principal en http://www.jasoft.org allí funcionaba, pero al ser una URL relativa aquí no 🙁

    Ya la he corregido. Gracias. A ver cuándo nos vemos que desde que no eres un Plain-tipo y ano se sabe nada de ti, jeje 🙂

    – José A.: no conocía tu post pero veo que es esencialmente lo mismo. Gracias por apuntarlo aunque el objetivo era diferente.

    Saludos!

    JM

  3. Jose, si vienes por Madrid avisa y hago por quedar, que tienes toda la razón. 😉

    Si voy a tu tierra trataré de avisar, que fuí hace poco pero iba a otros menesteres y no tuve tiempo para llamar a los amigos. 😉

    Abrazotes fiera.

  4. Tengo una duda: en donde se tiene if (!string.IsNullOrEmpty(objCookie.Value)), pues siempre va a retornar true porque anteriormente se le ejecutó HttpCookie objCookie = ctx.Request.Cookies[“ASP.NET_SessionId”].
    O no?

  5. Hola Jose,

    He entendido todo lo que explicas, pero no sé como puedo usar esta función sin tener que llamarla, es decir, que se pueda configurar en el web.config o algo así para que al detectar el fin de sesión se lance.

    Muchas gracias

  6. Hola a todos, tengo una duda que desearia saber si me pueden ayudar. Tengo un programa
    asp.net 2.0 donde los usuarios se logean con la autenticacion por formularios. Una vez
    logrados los usuarios trabajan con una base de datos sql en una tabla temporal con sus
    datos. Necesito borras los datos de la tabla cuando se ejecutar el timeOut de la
    autenticacion por formualrios. Puse un boton salir donde ejecuto el Singout y alli hago un
    delete a la base de datos con el nombre de usuario y listo…todo perfecto…ahora cuando al
    usurio se va atomar un cafe y vuelve y se acabo el tiemepo de autenticacion entra a un link
    y lo manda automaticamente a la pagina de login…ahi tambien tengo que borrar la
    informacion de este automaticamente en la tabla temporal y no se como hacerlo……desde ya
    muchas garcias

  7. buenas tardes, tengo una aplicacion en asp.net con c# y necesito poner un contador de entradas y que a las 3 vez que se logean erroneamente me tire un cartel, como lo hago?? si o si por codigo o algn algun validador o formaulario para facilitar eso
    desde ya muchas gracias

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *