Плохо ли иметь вызовы базы данных в классах фильтров?

У нас есть веб-приложение. Мы хотим предотвратить множественный вход одних и тех же пользователей. По сути, мы хотим, чтобы это произошло так:

  1. Джон входит в приложение как «user1».
  2. Машина Джона немного зависает по какой-то неизвестной причине.
  3. Джон не может ждать. Джон переходит на компьютер2, открывает там браузер и входит в систему как «пользователь1».
  4. Сеанс Джона в браузере на первом компьютере теперь должен быть аннулирован.

для этого мы планируем сохранять в базе данных все sessionId всех вошедших в систему пользователей. Это делается для того, чтобы проверить, не вошел ли другой пользователь с тем же именем на другом компьютере или использовал другой браузер на том же компьютере. Чтобы реализовать это, мы планируем выполнить проверку идентификатора сеанса в классе Filter, который проверяет сеанс. При этом будут вызовы базы данных каждый раз, когда вызывается класс Filter.

Это хорошая практика?

РЕДАКТИРОВАТЬ:

SessionId самого последнего пользователя, вошедшего в систему, всегда будет отслеживаться. Таким образом, в примере, когда Джон входит в систему с помощью браузера на машине 2, идентификатор сеанса, сохраненный в базе данных (с компьютера 1), будет переопределен идентификатором сеанса в браузере на компьютере 2. Теперь, когда браузер на компьютере1 снова используется, он автоматически аннулирует сеанс, поскольку обнаруживает, что идентификатор сеанса для пользователя теперь отличается.


person Davoin Showerhandles    schedule 01.12.2015    source источник
comment
Сеанс Джона в браузере на первом компьютере теперь должен быть признан недействительным. Как вы можете быть уверены, что не сделаете недействительным второй компьютер Джона?   -  person Manu    schedule 01.12.2015
comment
Вы хотите, чтобы сеансы были постоянными? Если нет, я не вижу необходимости хранить идентификаторы сеансов в базе данных. Просто держите их в памяти и проверяйте там. Если приложение кластеризовано, вам, возможно, придется предпринять некоторые дополнительные действия, но это все равно должно быть выполнимо таким образом.   -  person Thomas    schedule 01.12.2015
comment
Вы можете использовать локальное хранилище для хранения идентификатора сеанса, и если он использует второй браузер, вы можете добавить проверку, присутствует ли идентификатор сеанса или нет.   -  person Rohan Kawade    schedule 01.12.2015
comment
@Thomas: ты имеешь в виду использовать синглтоны? но мы не должны делать статические классы изменчивыми, верно?   -  person Davoin Showerhandles    schedule 01.12.2015
comment
@Rohan Kawade: ты имеешь в виду использовать файл?   -  person Davoin Showerhandles    schedule 01.12.2015
comment
Это был бы не совсем синглтон. Это было бы больше похоже на кеш, CDI-компонент области приложения и т. д. - сам экземпляр не был бы статичным.   -  person Thomas    schedule 01.12.2015
comment
@Davoin Showerhandles: см. этот stackoverflow.com/questions/ 13217423/   -  person Rohan Kawade    schedule 01.12.2015
comment
если вам ДОЛЖНО попасть в БД внутри фильтра, вы можете только сделать вызов максимально оптимизированным. spring-security оценивает пользователя по базе данных внутри своих фильтров, поэтому в этом подходе нет ничего плохого.   -  person injecteer    schedule 01.12.2015
comment
@Thomas: могу ли я также использовать для этого какой-нибудь сторонний кеш, например EhCache?   -  person Davoin Showerhandles    schedule 01.12.2015
comment
@injecteer: правда? я не знал этого о весенней безопасности   -  person Davoin Showerhandles    schedule 01.12.2015
comment
Да, EhCache и т. д. должны работать.   -  person Thomas    schedule 01.12.2015
comment
@DavoinShowerhandles, ну, springSecurityFilterChain определяется в web.xml как filter, так что да, это так. Мой вывод: не переусердствуйте и не оптимизируйте свое приложение преждевременно. Если кажется правильным что-то сделать где-то — делайте это, если нет реальных ограничений, о которых нужно беспокоиться. Чего вам действительно не следует делать, так это обращаться к базе данных внутри JSP-страницы, остальное зависит от вас.   -  person injecteer    schedule 01.12.2015


Ответы (1)


Это зависит от того, что вы называете вызовом базы данных. Вполне допустимо, что фильтр использует значение из базы данных. Но прямые вызовы базы данных в фильтре — действительно плохая практика, потому что она не учитывает многоуровневую разработку.

Мой совет заключается в том, что фильтр должен вызывать только сервисный уровень.

В комментарии приведен пример Spring Security, где база данных ролей пользователей используется в механизме фильтрации. Но на самом деле классы фильтров ничего не знают о базе данных и просят другие классы (эквивалент уровня обслуживания и сохранения) выполнить реальную работу.

TL/DR: использование данных, хранящихся в базе данных, в фильтре допустимо, следует избегать вызовов JDBC в фильтре.

person Serge Ballesta    schedule 01.12.2015