每次请求时 Laravel 的会话 ID 都会更改。

13
我有一个 Laravel 5.0 网站,其中前端 JS 经常向后端 Laravel 代码发出许多 ajax 请求。我注意到每次 ajax 请求都会在响应中得到一个新的“laravel_session”cookie 值。我猜这是一种防止会话劫持的安全机制。
然而,我认为这可能会导致我的网站出现问题,因为我的 ajax 调用通常是并行发生的,而不是按顺序等待响应后再发出下一个调用。
考虑以下情况:
- Ajax 调用1 - 请求 - laravel_session cookie = '1234' - Ajax 调用1 - 响应 - laravel_session cookie = '2345' - Ajax 调用2 - 请求 - laravel_session cookie = '2345' - Ajax 调用3 - 请求 - laravel_session cookie = '2345' - Ajax 调用2 - 响应 - laravel_session cookie = '3456' - Ajax 调用3 - 响应 - 会话已失效
有没有什么解决方法?
我还应该注意到,会话在 config/session.php 中设置为过期时间为 'lifetime' => 120,。

enter image description here

config/session.php


2
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - samlev
我的config/session.php文件中的设置看起来没问题,'files' => storage_path().'/framework/sessions',我可以看到在storage/framework/sessions/目录下创建了文件。 - MakkyNZ
对我来说,它是 'files' => storage_path('framework/sessions')。 - mroesler
5个回答

12

你是正确的,这是一种安全机制。要在测试时禁用它,在Kernel.php中注释掉这行代码:

\App\Http\Middleware\EncryptCookies::class

那么您将在cookie查看器中看到会话ID,而且它不会改变。

您可以通过Google搜索HTTP加密cookie来了解相关实践。目前有一个争论,即在每个网站上使用HTTPS后,这种旧的实践是否还必要。


为什么你这么说?那不是真的,而且你在建议某人禁用安全机制。 - hilnius
1
我正在点赞这个。问题归结为,“为什么会发生这种情况?是安全问题吗?” 我相信这个回答了这个问题。你可以注释掉这一行来验证它,但我不认为这是建议删除加密的意思。 - mikeDOTexe
谢谢,我编辑了答案以澄清为测试目的禁用。 - malhal

2
您的域名无效。您需要查看config.session.domainconfig.session.path

我已经将config/session.php中的“domain”设置更改为我的站点域名,但仍然遇到问题。“path”设置为“/”,在我看来似乎没问题。 - MakkyNZ
你确定域名是正确的吗?你能发另一张截图吗?我曾经也遇到过同样的问题,花了几个小时才意识到我不小心犯了一个小错误。 - Lance Pioch
我已经添加了截图。http://local.mysite.com是本地运行站点的URL。我为此设置了主机条目。 - MakkyNZ
我遇到了这个错误,而且是的,域名不正确。我必须死了,刚刚浪费了我4个小时的生命。-_- - ssi-anik

1
我遇到了同样的问题,尝试了很多解决方案,但都没有起作用。
我的情况是:只有当会话驱动程序设置为“数据库”时,令牌才会在每个请求中更改,而在“文件”和“Redis”驱动程序上运行良好。
经过大量调试,我发现问题不在会话配置中,而在DB中会话表中的“payload”列中。
我将“payload”列从文本更改为“longText”,然后它就起作用了!

1
同样的问题也发生在我身上,后来发现是因为我使用了
protected $middleware = [
     \Illuminate\Session\Middleware\StartSession::class,
     \Illuminate\View\Middleware\ShareErrorsFromSession::class
];
protected $middlewareGroups = [
     'web' => [
          \Illuminate\Session\Middleware\StartSession::class,
          \Illuminate\View\Middleware\ShareErrorsFromSession::class
     ]
]

由于在 $middleware 和 $middlewaregroups 中都使用了 session,导致在不同路由之间切换时创建了新的 session id。

那又怎样?请解释一下该怎么做?两者都启用吗?还是只保留网页? - undefined

0

关于会话有一些重要的事情。首先是cookie时间。如果您的Laravel应用程序的时区为UTC,但您的计算机的时区为+3,则如果您将cookie生存期设置为120(两个小时),则cookie将立即被浏览器删除。您必须增加cookie的生存期。

另一个选项是加密。Cookie始终是加密的。如果您在sessions.php文件中设置encrypt=true,则storage/framework/sessions文件夹将被加密。有时这会引起问题。如果会话不保留,请尝试将encrypt设置为false。之后,您可以看到会话文件未加密,并且它们具有“序列化”文本。然后您可以在其中查看会话变量。

另一个选项是sessions.php文件中的domain变量。您必须正确设置它或将其保留为空null。域名不能以http(s)://开头。只需在其中写入域名(例如yourdomain.com、yourdomain.test、yourdomain.host、www.yourdomain.com、subdomain.yourdomain.com等)。

另一个选项是关于driver的。如果将其设置为database,则必须确保表列具有足够的大小来存储大量会话数据。如果将其设置为file,则必须确保storage/framework/sessions文件夹可写且可读。

还有一个“小”(我认为很重要)的技巧。不要在会话中使用通用关键字。例如,不要使用'token'关键字。使用特定的会话名称。这是错误的:session(['token' => $result->token]),但这样做更好:session(['backend_remote_token' => $result->token])

摇滚...


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