我有一个 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 中设置为过期 “一生”=> 120,
你是对的,这是一种安全机制。要禁用它进行测试,请在 Kernel.php 中注释掉这一行:
\App\Http\Middleware\EncryptCookies::class
然后您将在 Cookie 查看器中看到会话 ID,并且它不会改变。
您可以Google一下HTTP加密cookie来了解一下做法。既然我们在每个网站上都使用 HTTPS,那么这种旧做法是否有必要一直存在争论。
您的域名无效。您需要查看
config.session.domain
和 config.session.path
。
我也出现了同样的问题,后来发现我正在使用
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 中,因为它在不同路由之间的移动中创建了一个新的会话 ID。
我也遇到了同样的问题,我尝试了很多解决方案,但没有任何效果。
我的案例: 仅当会话驱动程序设置为
database
时,令牌才会根据每个请求不断更改,并且它在 file
和 Redis
驱动程序上工作得很好。
经过大量调试,我发现问题不在于会话配置,而是来自数据库中会话表中的
payload
列。
我将
payload
列从文本更改为 longText
,并且成功了!
关于会议,有一些重要的事情。首先是饼干时间。如果你的 Laravel 应用程序的时区是 UTC,但你的计算机的时区是 +3,那么如果你将 cookie 生命周期设置为 120(两小时),那么 cookie 将立即被浏览器删除。您必须增加 cookie 的生命周期。
其他选项是加密。 Cookie 始终是加密的。如果您在
encrypt=true
文件中设置 sessions.php
storage/framework/sessions
文件夹将被加密。有时这会导致问题。如果会话未保留,请尝试将 encrypt
设置为 false
。之后,您可以看到会话文件未加密,并且它们具有“序列化”文本。然后你可以在那里看到你的会话变量。
其他选项是
domain
文件中的 sessions.php
变量。您必须正确设置它或保留它null
。域名最初不得有 http(s)://
。仅在其中写入域名(例如 yourdomain.com、yourdomain.test、yourdomain.host、www.yourdomain.com、subdomain.yourdomain.com 等...)。
其他选项是关于
driver
。如果将其设置为 database
,那么您必须确保表列有足够的大小来存储大会话数据。如果您将其设置为 file
,则必须确保 storage/framework/sessions
文件夹可写且可读。
还有一个“小”(我认为很重要)的技巧。不要在会话中使用通用关键字。例如,不要使用“令牌”密钥。为会话使用特定名称。这是错误的:
session(['token' => $result->token])
,但这更好:session(['backend_remote_token' => $result->token])
摇滚乐...
以防这影响到其他人。我的客户提供了他们的数据快照,因此我使用
Carbon::setTestNow
假装当前时间处于客户数据支持的时期内。
这导致会话 cookie 创建时带有过去的时间戳,因此它们会立即被浏览器过期。
对于我的模拟,我可以在数据库查询后再次调用
Carbon::setTestNow()
以避免出现问题。
虽然浪费了几个小时!