Как делать недействительным сеанс пользователя, когда он регистрируется дважды с теми же учетными данными

Я использую JSF 1.2 с Richfaces и Facelets.

У меня есть приложение со многими ограниченными по объему сессией бобами и некоторыми компонентами приложения.

Пользователь входит в систему с, скажем, Firefox. Сессия создается с идентификатором = "A"; Затем он открывает Chrome и входит в систему снова с теми же учетными данными. Сессия создается с идентификатором = "B".

Когда сессия "B" создается, я хочу смочь уничтожить сессию "A". Как сделать это?

Также. когда пользователь в Firefox делает что-либо, я хочу смочь отобразить всплывающее окно или некоторое уведомление, говоря, что "Вы вышлись из системы, потому что Вы вошли в систему от где-то в другом месте".

У меня есть sessionListener, кто отслеживает сессии, созданные и уничтоженные. Вещь, я мог сохранить объект HTTPSession в ограниченном по объему приложением бобе и уничтожить его, когда я обнаруживаю, что пользователь вошел в систему дважды. Но что-то мне подсказывает, что является просто неправильным и не будет работать.

JSF отслеживает сессии где-нибудь на стороне сервера? Как получить доступ к ним идентификатором? В противном случае, как выгнать первое, входят в систему пользователя, когда он входит в систему дважды?

19
задан BalusC 17 June 2013 в 11:05
поделиться

2 ответа

Независимый от БД подход заключался бы в том, чтобы позволить пользователю иметь статическую переменную Map и реализовать HttpSessionBindingListener Object # equals () и Object # hashCode () ). Таким образом, ваше веб-приложение по-прежнему будет работать после непредвиденного сбоя, который может привести к тому, что значения БД не будут обновлены (вы, конечно, можете создать ServletContextListener , который сбрасывает БД при запуске веб-приложения, но это только больше и больше работы).

Вот как должен выглядеть пользователь :

public class User implements HttpSessionBindingListener {

    // All logins.
    private static Map<User, HttpSession> logins = new ConcurrentHashMap<>();

    // Normal properties.
    private Long id;
    private String username;
    // Etc.. Of course with public getters+setters.

    @Override
    public boolean equals(Object other) {
        return (other instanceof User) && (id != null) ? id.equals(((User) other).id) : (other == this);
    }

    @Override
    public int hashCode() {
        return (id != null) ? (this.getClass().hashCode() + id.hashCode()) : super.hashCode();
    }

    @Override
    public void valueBound(HttpSessionBindingEvent event) {
        HttpSession session = logins.remove(this);
        if (session != null) {
            session.invalidate();
        }
        logins.put(this, event.getSession());
    }

    @Override
    public void valueUnbound(HttpSessionBindingEvent event) {
        logins.remove(this);
    }

}

Когда вы входите в систему пользователя следующим образом:

User user = userDAO.find(username, password);
if (user != null) {
    sessionMap.put("user", user);
} else {
    // Show error.
}

, тогда он вызывает valueBound () , который удалит всех ранее вошедших в систему пользователей из карты логинов и аннулирует сеанс.

Когда вы выходите из системы пользователя следующим образом:

sessionMap.remove("user");

или когда время ожидания сеанса истекло, то будет вызвана функция valueUnbound () , которая удалит пользователя из логины карта.

20
ответ дан 30 November 2019 в 04:29
поделиться
  1. создайте целочисленное поле в базе данных userLoggedInCount
  2. При каждом входе в систему увеличивайте этот флаг и сохраняйте результат в сессии.
  3. При каждом запросе проверяем значение в базе данных и значение в сессии, и если значение в сессии меньше значения в БД, аннулируем() сессию и уменьшаем значение в базе данных
  4. при уничтожении сессии уменьшаем и это значение.
4
ответ дан 30 November 2019 в 04:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: