Laravel TokenMismatchException session timeout

2019-06-24 05:54发布

问题:

I am running into an issue where when a user sits idle for more than 24 hours (my session timeout), or leaves the site and then comes back after 24 hours, they are not being logged out of the site, but their session is being expired, or at least their _token is no longer valid.

This causes unwanted behavior as if the user submits a form after their _token has expired and they now receive a TokenMismatchException.

Locally it seems that when the idle time exceeds the session lifetime the user is logged out, however in production on the live server this is not the case, the idle time can surpass the session lifetime and yet the user is still logged in and Auth::check() and Auth::user() both function as expected if a user were logged in.

What would cause the user to not be logged out, even though their session has expired?

Is there a way I can check that the session has expired so that I can then manually log the user out with a message asking them to log back in?

I have tried to use the App::before filter to check the last_activity on the session and determine if it has expired, but once the session has expired I no longer have access to it as it has been removed from the database, therefore I can not compare the timestamps to determine if the user needs to be manually logged out and prompted to re login.

My session config:

'driver' => 'database',

'lifetime' => 1440,

'expire_on_close' => false,

Thanks.

回答1:

I've also been struggling to find a solution to this problem for a long time. Everything goes fine 95% of the time, but some AJAX requests randomly die with this Illuminate\Session\TokenMismatchException error.

Just now I deployed a quick-and-dirty fix -- I put this piece of code into the layout:

setInterval(function () {
  $.get(window.location.origin + '/keepSessionAlive')
    .fail(function(response) {
      Sentry.trackError(
        'KeepSessionAlive request failed. ' +
        'Response: ' + JSON.stringify(response)
      );
    });
}, 300000);

As dump as it looks, it simply sends a request to the server every 5 minutes to make sure the session is kept alive.

(The /keepSessionAlive endpoint is under the web middleware group and just returns { success: true })

Hope it will make a difference :)