0

We have a Wicket web app with lots of AJAX buttons that change state etc., without doing a whole of page refresh - all typical stuff.

What we've noticed is that, after the session has timed out, if on a page requiring authentication, as we have auto logon via typical session/cookie technique, the page is simply re-rendered with no feedback to the user - but the click they made has been consumed and effectively ignored.

This can be a bit disheartening at times because they can click to change the state of something or start up a process and then move to a different tab in the browser or some other app only to find out, when they return to the Wicket app, that the state is not changed or the process has not started - it is like they never clicked the button.

Is there a standard way to handle these session timeouts in regard to AJAX clicks?

I tried adding an IRequestCycleListener:

public class SessionValidator implements AbstractRequestCycleListener {

        @Override
        public void onRequestHandlerScheduled(RequestCycle cycle, IRequestHandler handler) {
            if (handler instanceof AjaxRequestHandler) {
                boolean authenticated = false;
                
                if (Session.exists()) { 
                    SignIn2Session session = (SignIn2Session)Session.get();
                    
                    if (!session.isSessionInvalidated()) {
                        if (session.isSignedIn())
                            authenticated = true;
                    }
                }
                
                if (!authenticated) {
                    cycle.setResponsePage(SignIn2.class);
                }
            }
        }

But by the time the AjaxRequestHandler is being notified a page rendering handler has already gone in an refreshed the session and re-authenticated the user. So the AjaxRequestHandler always sees a valid session with an authenticated user.

Any suggestions of how to give some feedback to the user rather than just effectively ignoring their click?

I've even thought off turning of auto authentication altogether and forcing users to log in again (their browser will most likely have their password stored anyway so not such a big deal)

Volksman
  • 1,969
  • 23
  • 18
  • Does this answer your question? [Determine if $.ajax error is a timeout](https://stackoverflow.com/questions/3543683/determine-if-ajax-error-is-a-timeout) – Karl Knechtel May 26 '23 at 05:15
  • @KarlKnechtel The whole app is written in pure Java using Apache Wicket to specifically avoid having to do JS level stuff - that's all handled automagically by Wicket. There are ways to customize the JS from Wicket but I was hoping for a pure Java/pure Wicket solution. – Volksman May 26 '23 at 05:19
  • 1
    I would measure the session timeout in the application itself on the client side and warn the user about it, and maybe prevent ajax calls on timed out sessions, maybe with a small "time buffer" for compensation of server/client timings – cyberbrain May 26 '23 at 06:02

1 Answers1

0

Wicket pages which use Ajax are usually stateful. When the http session expires all pages associated with it are erased, i.e. all their state is lost. After re-authentication a completely new page instance is created with its initial state. Wicket cannot assume that the initial state is similar to the last state of the old session, so the Ajax request is ignored.

You can add usage of Session.get().info("...") in the re-authentication code to inform the user that (s)he needs to redo the last action.

martin-g
  • 17,243
  • 2
  • 23
  • 35
  • Does the String passed to Session#info() method automatically appear somewhere in the UI or does something elsewhere have to read that info text and display it? – Volksman May 26 '23 at 06:50
  • @Volksman the second one, you have to bring this message to UI. More info about flash message here: https://nightlies.apache.org/wicket/guide/9.x/single.html#_using_flash_messages – Andrea Del Bene May 26 '23 at 07:52