Deutsch
Germany.ruФорумы → Архив Досок→ Программирование

Вопросик из области Web-Programmierung, Java

08.09.15 11:52
Re: Вопросик из области Web-Programmierung, Java
 
MrSanders старожил
в ответ v0id* 07.09.15 16:08
Чтобы не забыть - проблема у нас такая:
В ответ на:
Надо не давать больше чем одному логину работать в одной и той же сессии. В разных сессиях можно сколько угодно разных логинов, но одна сессия - один логин.
Надо надежно отслеживать что пользователь прекратил работу, даже если он не делал логаут, а просто закрыл окно браузера.
сессия - на Томкате, с http, и абсолютно точно привязана к IP, это я проверил.

А как вы проверили? Лично я не знаю такой реализации Manager-а, который заставит томкат использовать одну и ту же сесстю для одного IP. Как у вас сконфигурирован Manager в Context-е?
Покажите код сервлета, который вызывается когда пользователь логинится. До логина апплет обращается к сервлету?
Допустим все именно так, у нас HttpSession, привязанная к IP и живущая 10 дней (кто ж до такого догадался-то...)
Кто виноват - понятно, аффтар жжот. Что делать? Ничего хорошего.
Апплет у вас как-то идентифицируется, несмотря на то что общение с сервером идет в одной сессии, или нет?
Т.е. если на одной машине открыты два окна, в обоих юзер залогинится используя один и тот же логин X, на сервлет пришел какой-то запрос, вы можете понять от какого из двух апплетов он пришел?
Если мы может разделять пользователей (для каждого запроса, пришедего на сервлет, мы можем прочитать из запроса или создать идентификатор клиента uniqueClientId), то сработает такое:
1. При логине смотрим в HttpSession (метод getAttribute(String))- есть ли у нас аттрибут CURRENT_LOGIN
1.1 нет аттрибута. Значит в этой сессии никто не залогинен. Разрешаем логин
session.setAttribute("CURRENT_LOGIN", uniqueClientId);
session.setAttribute("LAST_ACTION_TIME", System.currentTimeMillis());

1.2 есть аттрибут. Проверяем не вылетел ли этот пользоватль по таймауту. Читаем из сессии LAST_ACTION_TIME

final long currentTime = System.currentTimeMillis();
final boolean loginTimedOut;
if(session.getAttribute("LAST_ACTION_TIME")==null){
loginTimedOut = false;
} else {
final long lastActionTime = (Long)session.getAttribute("LAST_ACTION_TIME");
loginTimedOut = currentTime > lastActionTime + inactivityTimeout; // inactivityTimeout, например, равен 15*60*1000 (15 минут)
}

1.2.1 loginTimedOut == true. Пользователь с этим логином слишком долго ничего не делал. Меняем его логин.

session.setAttribute("CURRENT_LOGIN", uniqueClientId);
session.setAttribute("LAST_ACTION_TIME", System.currentTimeMillis());

1.2.2 loginTimedOut = false Логин активен - новый логин запрещен
2. При каждом запросе от апплета смотрим от кого он пришел, если ID логина (uniqueClientId) совпадает с тем, что в сессии в аттрибуте CURRENT_LOGIN лежит, актуализируем LAST_ACTION_TIME и выполняем запрос.
Если не совпадает (запрос может придти от старого апплета, с логином, который был замещен новым из-за неактивности) собщаем об ошибке и закрываем апплет.

 

Перейти на