Seguimiento de la caducidad de la sesión en el navegador

Entonces, existe esa compleja aplicación web heterogénea, con partes AJAX hechas tanto manualmente como por marcos, múltiples ventanas emergentes, etc. Un gran cliente respetable se acerca a usted con el requisito de invalidar, cerrar o realizar alguna otra actividad en toda la web. ventanas de la aplicación una vez que la sesión HTTP expira. Es de esperar que sepa cómo controlar el intervalo de tiempo de espera de la sesión HTTP, para una aplicación web compatible con J2EE, se hace desde un archivo web.xml (sin embargo, en muchos servidores de aplicaciones no se hace de manera estándar). Para un tiempo de espera de 10 minutos es:

  10  

El requisito del cliente no es absurdo en absoluto y tiene mucho sentido desde la perspectiva del usuario final, pero puede convertirse en un dolor terrible para un desarrollador porque: 1. No puede simplemente iniciar un temporizador de cuenta regresiva en la ventana del navegador cada vez que se carga la página. para cerrar la ventana en el tiempo de espera. Este enfoque funcionó en un mundo no AJAX cuando cada interacción navegador-servidor resultó en la recarga de la ventana del navegador. 2. No puede consultar al servidor para verificar si la sesión HTTP ha agotado el tiempo de espera o no, ya que cada consulta de este tipo se tratará como una interacción navegador-servidor que prolonga la sesión. Esto conducirá a una sesión que nunca expira. 3. Puede crear una aplicación web separada que tenga en cuenta la sesión HTTP de la aplicación web principal y se cruce con ella. Pero eso es una exageracióny las posibilidades de que dicha solución sea aceptada son extremadamente bajas debido a los problemas de integración que pueden surgir. 4. Puede intentar interceptar todas las interacciones navegador-servidor AJAX con algún código avanzado similar a un hack, y le ayudará a lidiar con su ventana actual. Pero esto no funciona para el caso de múltiples ventanas abiertas, simplemente no puede comunicarse entre las ventanas del navegador. La única forma de hablar con alguna ventana abierta desde una principal es usar la referencia de JavaScript de otra ventana, y una vez que la ventana principal se recarga o se dirige a una ubicación diferente, pierde todas las referencias de JavaScript a otras ventanas. 5. El enfoque más realista es realizar solicitudes periódicas de JavaScript XMLHTTP (desde cada ventana abierta) al servidor cada {intervalo máximo inactivo de sesión} +10 segundos. Esto eventualmente cerrará todas las ventanas,pero puede dar como resultado que las ventanas se cierren minutos (o incluso horas, dependiendo de la configuración del tiempo de espera de la sesión de la aplicación web) después de que la sesión HTTP se destruye, por ejemplo, una vez que el usuario cierra la sesión desde la ventana principal. No quedan más opciones, estás frustrado y piensas que es el momento adecuado para tomar el arma de tu papá y dispararle a tus compañeros en la escuela mañana. No, todavía no, niño, ¡todavía hay una salida! La salida no es muy sencilla, pero sí muy elegante. Las cookies nos ayudarán. Se podría pensar que el tiempo de caducidad de las cookies funcionaría. Desafortunadamente, como se describe enEs el momento adecuado para tomar el arma de tu papá y dispararle a tus compañeros en la escuela mañana. No, todavía no, niño, ¡todavía hay una salida! La salida no es muy sencilla, pero sí muy elegante. Las cookies nos ayudarán. Se podría pensar que el tiempo de caducidad de las cookies funcionaría. Desafortunadamente, como se describe enEs el momento adecuado para tomar el arma de tu papá y dispararle a tus compañeros en la escuela mañana. No, todavía no, niño, ¡todavía hay una salida! La salida no es muy sencilla, pero sí muy elegante. Las cookies nos ayudarán. Se podría pensar que el tiempo de caducidad de las cookies funcionaría. Desafortunadamente, como se describe en

esta

artículo, no puede confiar en el tiempo de vencimiento de las cookies ya que lo mide el navegador del cliente, y nadie puede garantizar que el reloj del sistema del cliente no tenga un año de retraso. Entonces, aquí está el sistema y el método para rastrear los tiempos de espera de las sesiones HTTP en aplicaciones web heterogéneas. En cada solicitud realizada desde un navegador a un servidor, un filtro de servlet establece dos cookies. Uno mantiene la hora actual del servidor y otro mantiene la hora de expiración de la sesión. La hora actual del servidor solo es necesaria para calcular un desplazamiento entre el cliente y el servidor. El tiempo de vencimiento de la sesión se verifica periódicamente con el tiempo del servidor _calculado_ actual (recuerde el desplazamiento). Cada vez que _cualquier_ solicitud se realiza al servidor, la cookie de tiempo de vencimiento se actualiza y todo funciona. En la práctica, este método se realiza en solo tres pasos: 1.Cree un filtro de servlet que filtraría todas y cada una de las solicitudes a su aplicación web. Configúrelo en web.xml así:

  SessionTimeoutCookieFilter some.package.SessionTimeoutCookieFilter   SessionTimeoutCookieFilter /*  

No se preocupe por el rendimiento de su aplicación web: este filtro es MUY primitivo, todo lo que hace es agregar dos cookies a la respuesta:

 public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException { HttpServletResponse httpResp = (HttpServletResponse) resp; HttpServletRequest httpReq = (HttpServletRequest) req; long currTime = System.currentTimeMillis(); long expiryTime = currTime + session.getMaxInactiveInterval() * 1000; Cookie cookie = new Cookie("serverTime", "" + currTime); cookie.setPath("/"); httpResp.addCookie(cookie); if (httpReq.getRemoteUser() != null) { cookie = new Cookie("sessionExpiry", "" + expiryTime); } else { cookie = new Cookie("sessionExpiry", "" + currTime); } cookie.setPath("/"); httpResponse.addCookie(cookie); filterChain.doFilter(req, resp); } 

Establecer la ruta (en "/" en nuestro caso) es muy importante. Si omite la configuración de la ruta, el navegador la calculará automáticamente a partir de la URL, lo que provocará un caos dentro del almacenamiento de cookies de su navegador. 2. Necesitamos un pequeño JavaScript en cada ventana para calcular el desplazamiento entre la hora del servidor y del cliente. Debe ejecutarse solo una vez, pero no estaría de más ejecutarlo en cada carga de página:

 function calcOffset() { var serverTime = getCookie('serverTime'); serverTime = serverTime==null ? null : Math.abs(serverTime); var clientTimeOffset = (new Date()).getTime() - serverTime; setCookie('clientTimeOffset', clientTimeOffset); } window.onLoad = function() { calcOffset(); }; 

3. Y finalmente necesitamos una función que realmente verifique si la sesión ha expirado. Debe ejecutarse periódicamente, en nuestro caso cada 10 segundos (o 10000 milisegundos):

 function checkSession() { var sessionExpiry = Math.abs(getCookie('sessionExpiry')); var timeOffset = Math.abs(getCookie('clientTimeOffset')); var localTime = (new Date()).getTime(); if (localTime - timeOffset > (sessionExpiry+15000)) { // 15 extra seconds to make sure window.close(); } else { setTimeout('checkSession()', 10000); } } 

De hecho, cerrar las ventanas del navegador al finalizar la sesión es pura brutalidad, y puede y debe ir acompañado de un mensaje de advertencia que aparece como 1 minuto antes de que finalice la sesión. Estoy realmente interesado en recibir tu

retroalimentación crítica

en mi método.

Esta historia, "Seguimiento de la caducidad de la sesión en el navegador" fue publicada originalmente por JavaWorld.