Проследяване на изтичането на сесията в браузъра

Така че, има онова сложно хетерогенно уеб приложение, с AJAX части, направени както ръчно, така и чрез рамки, множество изскачащи прозорци и т.н. Голям уважаван клиент се обръща към вас с изискване да обезсили, затвори или да извърши някаква друга дейност в цялата мрежа прозорци на приложения след изтичане на HTTP сесията. Надяваме се, че знаете как да контролирате интервала за изчакване на HTTP сесията, за съвместимо с J2EE уеб приложение това се прави от файл web.xml (обаче в много сървъри за приложения това не е по стандартен начин). За 10 минути таймаут е:

  10  

Изискването на клиента изобщо не е абсурдно и е напълно логично от гледна точка на крайния потребител, но може да се превърне в ужасна болка за разработчика, защото: 1. Не можете просто да стартирате таймер за обратно отброяване в прозореца на браузъра при всяко зареждане на страницата за затваряне на прозореца при изчакване. Този подход работи в свят, различен от AJAX, когато всяко взаимодействие между браузър и сървър води до презареждане на прозореца на браузъра. 2. Не можете да запитвате сървъра, за да проверите дали HTTP сесията е изтекла или не, тъй като всяка такава заявка ще се третира като взаимодействие браузър-сървър, удължаваща сесията. Това ще доведе до никога изтичаща сесия. 3. Можете да създадете отделно уеб приложение, което да знае за HTTP сесията на основното уеб приложение и да се пресича с него. Но това е прекалено много,и шансовете такова решение да бъде прието са изключително ниски поради проблеми с интеграцията, които вероятно ще възникнат. 4. Можете да опитате да прихванете всички взаимодействия на AJAX браузър-сървър с някакъв усъвършенстван хакерски код и това ще ви помогне да се справите с текущия си прозорец. Но това не работи за случая с множество отворени прозорци - просто не можете да комуникирате между прозорците на браузъра. Единственият начин да се говори с някой отворен прозорец от първичен е да се използва препратка към JavaScript на друг прозорец и след като основният прозорец бъде презареден или насочен към друго място, той губи всички препратки към JavaScript към други прозорци. 5. Най-реалистичният подход е да се правят периодични заявки за JavaScript XMLHTTP (от всеки отворен прозорец) към сървъра на всеки {сесия макс неактивен интервал} +10 секунди. Това в крайна сметка ще затвори всички прозорци,но може да доведе до минути на затваряне на прозорци (или дори часове в зависимост от настройката за изчакване на сесията в уеб приложението) след унищожаване на HTTP сесията, например след като потребителят излезе от основния прозорец. Няма повече опции, вие сте разочаровани и смятате, че е точно моментът да вземете пистолета на баща си и да застреляте съучениците си утре в училище. Не, още не хлапе - все още има изход! Изходът не е много ясен, но е много елегантен. Бисквитките ще ни помогнат. Може да се мисли, че времето за изтичане на бисквитките ще свърши работа. За съжаление, както е описано ве точното време да вземете пистолета на баща си и да застреляте съучениците си в училище утре. Не, още не хлапе - все още има изход! Изходът не е много ясен, но е много елегантен. Бисквитките ще ни помогнат. Може да се мисли, че времето за изтичане на бисквитките ще свърши работа. За съжаление, както е описано ве точното време да вземете пистолета на баща си и да застреляте съучениците си в училище утре. Не, още не хлапе - все още има изход! Изходът не е много ясен, но е много елегантен. Бисквитките ще ни помогнат. Може да се мисли, че времето за изтичане на бисквитките ще свърши работа. За съжаление, както е описано в

това

статия, не можете да разчитате на времето за изтичане на бисквитките, тъй като то се измерва от клиентски браузър и никой не може да гарантира, че клиентският часовник на системата не изостава с една година. И така, ето системата и методът за проследяване на HTTP сесиите в хетерогенни уеб приложения. При всяка заявка, направена от браузър към сървър, две бисквитки се задават от филтър за сървлети. Един държи текущото време на сървъра, а друг - времето на изтичане на сесията. Текущото време на сървъра е необходимо само за изчисляване на изместване между клиент и сървър. След това времето на изтичане на сесията се проверява периодично спрямо _calculated_ текущото време на сървъра (не забравяйте отместването). Всеки път, когато се направи всяка заявка _ към сървъра, бисквитката за времето на изтичане се актуализира и цялото нещо просто работи. На практика този метод се реализира само в три стъпки: 1.Създайте филтър за сървлети, който да филтрира всяка заявка към вашето уеб приложение. Конфигурирайте го в web.xml по следния начин:

  SessionTimeoutCookieFilter some.package.SessionTimeoutCookieFilter   SessionTimeoutCookieFilter /*  

Не се притеснявайте за ефективността на вашето уеб приложение - този филтър е МНОГО примитивен, а само добавя две бисквитки към отговора:

 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); } 

Задаването на път (до "/" в нашия случай) е много важно. Ако пропуснете настройката на пътя, браузърът автоматично ще го изчисли от URL адреса, което ще доведе до хаос в хранилището на бисквитките на вашия браузър. 2. Имаме нужда от малък JavaScript на всеки прозорец, за да изчислим отместването между времето на сървъра и клиента. Трябва да се стартира само веднъж, но не би навредило да се стартира при всяко зареждане на страница:

 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. И накрая се нуждаем от функция, която всъщност да проверява дали сесията е изтекла. Трябва да се изпълнява периодично, в нашия случай на всеки 10 секунди (или 10000 милисекунди):

 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); } } 

Всъщност затварянето на прозорци на браузъра след изтичане на сесията е чиста бруталност и може и трябва да бъде придружено от предупредително съобщение, което се появява около 1 минута преди изтичането на сесията Наистина ми е интересно да получа твоя

критична обратна връзка

по моя метод.

Тази история „Проследяване на изтичането на сесията в браузъра“ първоначално е публикувана от JavaWorld.