ТЛ; др
Простое существование пользовательского объекта входа в систему пользователя, хранящегося в качестве атрибута в хранилище значений ключей вашего VaadinSession
, представляет пользователя, успешно прошедшего аутентификацию. Нет необходимости во всем написанном вами коде слушателя сессии.
Пусть Ваадин сделает тяжелую работу
Я подозреваю, что вы слишком усердно работаете.
Нет необходимости для слушателей вашего сеанса. Vaadin обрабатывает почти все детали Java-сервлета от нашего имени.
Нет необходимости в перенаправлениях . Как разработчик Vaadin, вы полностью контролируете содержимое, отображаемое во вкладке / окне браузера, так что вы можете переключаться между формой входа и основным содержимым приложения. Предостережение: я новичок в функции @Route
в Vaadin Flow, так что может быть более изящный способ переключения между входом в систему и основным контентом. И если вы используете @Route
для нескольких представлений, каждое из этих представлений должно проверить аутентификацию, как описано ниже.
VaadinSession
В точке входа вашего кода приложения Vaadin получите текущий объект VaadinSession
. Этот VaadinSession
является оберткой вокруг класса javax.servlet.http.HttpSession
, определенного спецификацией Java Servlet . Vaadin автоматически создает экземпляр сеанса, когда браузер пользователя впервые подключается к вашему веб-приложению Vaadin (фактически, Vaadin переносит сеанс, созданный вашим веб-контейнером ). Сеанс автоматически закрывается, когда браузер закрывает свою вкладку / окно, происходит тайм-аут неактивности или вы закрываете сеанс программным способом.
VaadinSession vaadinSession = VaadinSession.getCurrent() ;
Атрибуты сеанса (хранилище значений ключей)
Опросить значение ключа этого сеансового объекта, известное как «атрибуты». Ключ имеет тип String
, а значение имеет тип Object
(суперкласс всех объектов Java). После получения объекта Object
вы переходите к известному классу. Вы знаете класс, потому что именно ваш код хранит атрибут.
Ваш логин пользователя
Вы бы определили класс для хранения информации, связанной с вашим логином. Возможно, вы назвали это UserLogin
.
Что-то вроде:
public class UserLogin {
// Member values.
String userName ;
Instant whenAuthenticated ;
// Constructor.
public UserLogin( String userNameArg , Instant whenAuthenticatedArg ) {
this.userName = userNameArg ;
this.whenAuthenticated = whenAuthenticatedArg ;
}
}
Попытка получить объект вашего класса входа в систему из хранилища значений ключей сеанса
Получить такой объект такого типа из хранилища значений ключей атрибутов сеанса.
String attributeName = "my-user-login" ;
UserLogin userLogin = vaadinSession.getAttribute( attributeName ) ;
Вместо того, чтобы придумывать имя атрибута, вы можете просто использовать имя класса. Класс Class
позволяет запрашивать имя класса в виде текста.
String attributeName = UserLogin.class.getName() ;
UserLogin userLogin = vaadinSession.getAttribute( attributeName ) ;
Если вы хотите использовать имя класса в качестве ключа таким образом, класс VaadinSession
предоставляет ярлык.
UserLogin userLogin = vaadinSession.getAttribute( UserLogin.class ) ;
Проверьте, является ли ваш UserLogin
объект нулевым. Если вы получили null
, то вы знаете, что еще не сохранили атрибут (или умышленно сохранили ноль).
Если не ноль, это означает, что у вашего пользователя уже сохранен активный UserLogin
объект. Как они могли войти в систему уже, если точка входа вашего приложения выполняется? Это может произойти, если пользователь нажмет кнопку Обновить в своем окне браузера. (Научите пользователя не делать этого в одностраничном веб-приложении , например, Vaadin.)
Схема кода для записи
UserLogin userLogin = vaadinSession.getAttribute( UserLogin.class ) ;
if( Objects.isNull( userLogin ) ) {
… display login form …
… when authenticated, instantiate a `UserLogin` and store as attribute …
if( authenticationSuccessful ) { // Testing some did-user-authenticate variable you defined in your login-form.
Instant whenAuthenticated = Instant.now() ; // Capture the current moment in UTC.
UserLogin userLogin = new UserLogin( userName , whenAuthenticated ) ;
VaadinSession.getCurrent().setAttribute( UserLogin.class , userLogin ) ; // Using class name as the `String` key tracking this `userLogin` object.
… switch content of the tab/window from authentication form to your main app content …
}
} else { // Else not null. User already authenticated. User may have hit "Reload" button in browser.
… display app content …
… perhaps log this event … maybe user needs to be trained to not hit Reload on a Single-Page Web App …
}
Кстати, рассмотренное выше обсуждение сессий распространяется на собственное подключение каждого пользователя к вашему веб-приложению в одной вкладке / окне веб-браузера.
В какой-то момент вы можете найти хук в жизненном цикле всего вашего веб-приложения, прежде чем первый пользователь подключится и / или после того, как последний отключится, узнайте о хуке, определенном в спецификации Java-сервлета. Этот хук представляет собой интерфейс ServletContextListener
, где «контекст» означает ваше веб-приложение в целом. Это стандартный материал сервлетов Java, совсем не специфичный для Vaadin, но Vaadin на самом деле является сервлетом (возможно, самым сложным из когда-либо существовавших сервлетов), поэтому применима эта парадигма прослушивания контекста.
Вы пишетекласс, реализующий этот интерфейс, путем написания методов before-first-user и after-last-user. Идентифицируйте свой класс в веб-контейнере, отмечая @WebListener
(или альтернативные средства). Переполнение стека поиска, поскольку это уже было рассмотрено несколько раз.