Laravel TokenMismatchException会话超时

4
我遇到了一个问题,当用户空闲时间超过24小时(我的会话超时时间)或者离开网站24小时以上后再回来时,他们不会被注销,但是他们的会话已经过期了,至少他们的_token不再有效。
这会导致一些不必要的行为,如果用户在_token过期后提交表单,他们现在会收到一个TokenMismatchException。
本地测试似乎当闲置时间超过会话寿命时,用户会被登出。然而,在实际生产环境中,即使空闲时间超过会话寿命,用户仍然保持登录状态,并且Auth::check()和Auth::user()都可以按预期工作,就好像用户已经登录一样。
是什么原因导致用户没被注销,即使他们的会话已经过期了?
有没有一种方式可以检查会话是否已过期,以便我可以手动注销用户并提示他们重新登录?
我尝试使用App::before过滤器来检查会话上的last_activity并确定它是否已过期,但是一旦会话过期,我就无法访问它,因为它已经从数据库中删除了,因此我无法比较时间戳以确定是否需要手动注销用户并提示重新登录。
我的会话配置:
'driver' => 'database',

'lifetime' => 1440,

'expire_on_close' => false,

感谢您的选择。

您是否有一个 config/production/session.php 文件可能覆盖了默认值? - Laravelian
不,我只有一个用于开发的config/local/session.php文件,以及一个默认的config/session.php文件用于生产环境。需要补充说明的是,这两个文件除了“lifetime”值不同之外,其他都是相同的。在开发环境中,“lifetime”值较短,以进行测试。 - Vigs
这正是一个难题。你找到任何解决方案或变通方法了吗? - lunacafu
我一直没有找到问题的原因或解决方案。有些用户告诉我,他们没有遇到这个问题,这增加了额外的复杂性,因为它并不影响所有用户,只影响一些人,包括我自己。 - Vigs
1个回答

0

我也一直在苦苦寻找解决这个问题的方法。95%的时间一切都很顺利,但有些 AJAX 请求会随机死亡,出现 Illuminate\Session\TokenMismatchException 错误。

刚才我部署了一个快而简单的修复方法——我将这段代码放入布局中:

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

尽管看起来很简单,但它只是每5分钟向服务器发送一个请求,以确保会话保持活动状态。

/keepSessionAlive端点位于web中间件组下,并且只返回{ success: true }

希望这会有所帮助 :)


1
每当捕获到TokenMismatchException时,您可以将用户重定向到登录页面。他们已经在Github上创建了一个问题(https://github.com/laravel/framework/issues/8172)。 - Fahmi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接