Laravel 5.1随机丢失会话数据

6
我在 Laravel 5.1 应用程序中遇到了一个奇怪的问题。
有时会丢失会话数据。我编写了一些中间件,将该请求的会话内容写入日志文件来检测这个问题。虽然会话 ID(Session::getId())没有改变,但使用Session::all()检索的会话数据中的_token值确实发生了变化。
正如我所说,这种情况是间歇性的。我可以多次刷新同一 URL,然后随机地在一次刷新中会话数据丢失,而_token值与之前的请求不同。
这是什么原因?我还注意到“丢失”的会话数据中没有flash对象。
以下是日志的一部分。您可以看到session_data键的内容在最后两行中随机更改了“形状”,但会话 ID 保持不变。
此外,不确定是否相关,但我启用了 DebugBar

Screen-shot

更新: 经过调试,我发现在某些页面加载时,会话完全为空,也就是说,没有_token(因此会生成一个新的)。什么都没有。


这种情况发生的频率有多高?因为我已经尝试通过启用DebugBar、创建一个记录会话ID和数据的中间件,就像你所做的那样,然后调用一个每秒自动刷新的视图路由,并将其保持约10分钟。但它没有刷新CSRF令牌或删除任何会话数据。这是使用artisan servefile会话驱动程序完成的,因此您可能需要发布有关您的环境的更多信息。 - Bogdan
每一两分钟就会发生这种情况。应用程序正在Apache下运行。我可以刷新URL,但在多次刷新后,它会随机丢失数据,如屏幕截图所示。没有真正的模式,这使得寻找原因变得困难。 - Martin Bean
我的第一个建议是尝试在干净的 Laravel 安装上复现问题,类似于我在第一条评论中描述的内容,至少可以确定问题是出在你的应用代码还是设置中的其他问题。 - Bogdan
在L4,2上搜索类似问题后发现了这个问题。当脚本完成时,会写入会话。有可能脚本根本没有完成,而是被杀死了吗?我曾经在一些使用字节缓存和重型AJAX页面的VPS服务器上看到过这种情况——太多的快速请求导致HTTP500错误,并且PHP处理程序因某种内存违规而死亡。在这些情况下,会话将不会被写入。 - Jason
我有同样的问题。
  1. 当响应返回为view::make()时,它可以正常工作。
  2. 当响应通过response()->json()返回时,它会刷新session._token哈希值。
- Cioxideru
3个回答

3
  1. 如果你正在使用文件驱动,可能会遇到并发请求时的竞争条件问题。文件被截断后,Laravel 无法读取文件,因此会刷新会话。竞争条件也会导致一些你放入会话中的内容没有被放入,这往往是随机的,非常难以调试。根据 Laravel 团队的说法,这是文件驱动的已知限制,并且似乎不会得到修复,因此建议使用其他驱动程序。这将解决随机会话刷新的问题,但仍会出现未能添加会话更改的可能性。据我所知,在 Laravel 5.1 中,您需要自行管理这一点。

  2. 某种情况下,您的会话数据过长而被截断。如果您正在使用数据库驱动程序(未测试其他驱动程序),并尝试保存超过字段长度的会话数据,则随后的请求将无法从该会话中获取数据,并且您将得到一个新的会话。如果这个问题在非常短的会话数据中随机发生,则很可能是上述原因造成的。


我刚刚花了两天时间追踪这个问题,结果发现问题出在#1处。由于其他原因,我们尝试引入一个不存在的JS文件。这个请求必须通过应用程序/路由器才能解析为404,这导致了竞争条件。移除虚假js文件的链接似乎解决了这个问题。谢谢! - Clayton

0

如果您使用Linux,请尝试在Laravel中使用Redis (http://redis.io)作为会话/缓存管理器。过去我曾在一些服务器上使用文本/cookie和Laravel时遇到了一些问题,但是当我安装了Redis之后就再也没有出现过问题了。

更多信息:https://laravel.com/docs/5.1/redis


谢谢,但另一种驱动程序并不能真正解决问题。我们的暂存环境正在使用文件驱动程序,这就是问题出现的地方。 - Martin Bean
你可以尝试一下数据库驱动吗?它会将数据持久化到数据库表中,也许会起作用。https://laravel.com/docs/5.1/session - Marcos Riso
一直在使用数据库驱动程序,但问题仍然存在。不确定是否是驱动程序的问题。我注意到这种情况经常发生在中间件中,如果我们在刀片上打印,它就可以正常显示。不确定发生了什么奇怪的事情... - Daksh Mehta

0

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