I’m experiencing an issue regarding session timeouts.
Basically what I think happens is that there has been a service restart or something that causes the cookie to no longer be bound to a session.
I can replicate the problem by simply deleting the JSESSION cookie from the browser.
What I see happening is that the /?v-r=uidl&v-uiId=0 call, that happens when I do a user action, returns a 302 redirect to the login page. This is because of a filter we have in the application that checks if there is a session known for the request, and if not it redirects to login page. This is handled through a filter because reasons …
Now, what I see happening is that a network call happens to fetch the login page, and then the UI shows a error message saying that what it gets back from the server is invalid JSON.
Basically I’m in a scenario where the front-end can no longer contact the vaadin backend, so I assumed I need to handle this error with a custom-error-handler.js, client-side, so I can redirect without having to call the Vaadin service.
I tried a couple of things, but i think I’m just not listening to the correct event to react upon.
Another option is to make the filter set a 401 status code. This way Flow client will handle the response as a session expiration and behave according the System Messages configuration
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
// Get the session from the backend based on the servletRequest
final SessionState sessionState = SessionStateManager.getSessionState(servletRequest);
if (sessionState == null || sessionState.getUserId() == null) {
HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
httpResponse.getWriter().flush();
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
}
and then added a SystemMessagesProvider to configure the login page:
event.getSource().setSystemMessagesProvider((SystemMessagesProvider) systemMessagesInfo -> {
CustomizedSystemMessages customizedSystemMessages = new CustomizedSystemMessages();
customizedSystemMessages.setSessionExpiredURL("/home/logon.html");
customizedSystemMessages.setSessionExpiredCaption("Session expired");
customizedSystemMessages.setSessionExpiredNotificationEnabled(true);
customizedSystemMessages.setSessionExpiredMessage("Click here to return to the login page");
return customizedSystemMessages;
});
This results in the following message to be shown
When the user clicks the message, he navigates to the login page.
For now, this is OK, I think … ideally I wanted to go for an automated redirect to be sure no sensitive data remains visible on screen.