Session Timeout Message in RoR using Devise

2020-07-13 07:34发布

问题:

I have an application secured with devise and a session timeout of 30 minutes. With devise all is working well for normal navigation, if the user clicks on a link when timed out they get redirected back to the login screen with a message saying "Your session expired, please sign in again to continue.", excellent.

However I have ajax in a lot of places. If the session times out and the user does an ajax operation I want the same behavior as above rather that silently failing with a 401 error in the background.

So far I have this jquery code on each page to catch 401s and reload:

$(document).ajaxError(function(e, error) {
  switch(error.status) {

    case 401: {
      // unauthorised (possible timeout)
      location.reload();
      break;
    }

It works well enough, but there is an annoying issue:

Because the ajax request hits devise first, when my application reloads the page I get directed to the login page, but I don't see the timeout message, I see the unauthenticated "You need to sign in or sign up before continuing." message.

Is there a way to ensure that on the second request devise still shows the timeout message?

回答1:

i think that you need to manually show this message, for example by redirecting to a specific url or setting some query parameter.

the problem is, that after your 401 request you got a new session and when you reload the browser, the next request will hit your application with an empty session. that's why you get the unauthenticated message.



回答2:

The timeout message "Your session expired. Please sign in again to continue" is available in xhr.responseText, so one approach would be to just display that:

$(document).ajaxError(function(e, error) {
  switch(error.status) {

    case 401: {
      // unauthorised (possible timeout)
      location.reload();
      alert(xhr.responseText);
      break;
    }

To me this seems to flow better: click Update on an Ajax form, get an alert that the session has timed out, then see "You need to sign in or sign up before continuing" in the flash on the signin page.