Пользовательские сессии с Vaadin Flow

В настоящее время я начинающий Java-разработчик, который хочет заняться разработкой Vaadin, и в настоящее время пытаюсь реализовать логин User Session для моего приложения. Я прочитал о содержании, касающемся использования VaadinServlets для этого: https://vaadin.com/docs/v10/flow/advanced/tutorial-application-lifecycle.html.

После неустанного поиска документации API и примеров кодов я все еще не могу понять, как реализовать пользовательские сеансы для конкретного пользователя, который входит в мою платформу. Из того, что я понимаю, я могу инициализировать сеанс пользователя, используя то, что я реализовал ниже.

Однако мои цели для приложения немного отличаются:

[Вариант использования]

1. Пользователь входит в систему со своими учетными данными.

2. Получает перенаправление на SecuredPage (который создаст сеанс пользователя, в котором хранится имя пользователя пользователя и получает токен?)

3. Через 2-3 минуты бездействия Пользователь будет вынужден выйти из SecuredPage, и сессия закроется?

@WebServlet(urlPatterns = "/*", name = "VaadinFlowServlet", asyncSupported = true)
@VaadinServletConfiguration(heartbeatInterval = 5, productionMode = false)
public class LoginServlet extends VaadinServlet implements SessionInitListener, SessionDestroyListener {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoginServlet.class);

    // <Method> ::servletInitialized():: -> handles most of the servlet customization. (write my servlet customization under this function.
    //          ::getService()::         -> returns a VaadinServletService type?
    //          ::addSessionInitListener(this)::    -> An event listener that can be registered to a VaadinService to get an event -> when a new Vaadin service session is initialized for that service.
    //          ::addSessionDestroyListener(this):: -> A listener that gets notified when a Vaadin service session is no longer used.
    @Override
    protected void servletInitialized() throws ServletException {
        super.servletInitialized();
        getService().addSessionInitListener(this);
        getService().addSessionDestroyListener(this);

    }

    // <Method>     ::sessionInit::      -> Starts Session?
    // <Parameter>  ::SessionInitEvent:: -> Event gets fired when a new Vaadin service session is initialized for a Vaadin service.
    @Override
    public void sessionInit(SessionInitEvent event) throws ServiceException{
        // Do Session start stuff here
        // Creates a Session?

        LOGGER.info("session init() "
                + " Session-ID: " + event.getSession().getSession().getId()
                + " CSRF: " + event.getSession().getCsrfToken());

    }

    // <Method>     ::sessionDestroy:: -> Stops Session?
    // <Parameter>  ::SessionDestroyEvent:: -> Event fired when a Vaadin service session is no longer in use.
    @Override
    public void sessionDestroy(SessionDestroyEvent event) {
        // Do session end stuff here
        LOGGER.info("session destory()");
    }

    }

+1 Значит, мне интересно, может кто-нибудь помочь мне лучше понять этот вопрос? Полностью оценен

1 ответ

ТЛ; др

Простое существование пользовательского объекта входа в систему пользователя, хранящегося в качестве атрибута в хранилище значений ключей вашего VaadinSession представляет пользователя, успешно прошедшего аутентификацию. Нет необходимости во всем написанном вами коде слушателя сеанса.

Пусть Ваадин делает тяжелую работу

Я подозреваю, что вы слишком усердно работаете.

Там нет необходимости для ваших слушателей сессии. Vaadin обрабатывает почти все детали Java-сервлета от нашего имени.

Нет необходимости в перенаправлениях. Как разработчик Vaadin, вы полностью контролируете содержимое, отображаемое во вкладке / окне браузера, так что вы можете переключаться между формой входа и основным содержимым приложения. Предостережение: я новичок в @Route особенность в Vaadin Flow, так что может быть более изящный способ переключения между входом в систему и основным контентом. И если вы используете @Route для нескольких представлений каждое из этих представлений должно проверяться на аутентификацию, как описано ниже.

VaadinSession

В точке входа кода вашего приложения Vaadin получите текущий VaadinSession объект. это VaadinSession это обертка вокруг javax.servlet.http.HttpSession класс, определенный спецификацией сервлета Java. 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 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 (или альтернативные средства). Переполнение стека поиска, поскольку это уже было рассмотрено несколько раз.

Другие вопросы по тегам