Ami*_*mir 11 php session laravel laravel-4
我们在我们的网站上遇到过这个问题,我们从用户那里得到了CSRF错误.会话cookie和会话数据设置为在12小时内过期,会话驱动程序设置为使用Redis.在我们的调查之后,我们最终成功地模拟了异常情况,所以这里是场景:
用户在网站上打开两个不同的页面,使用Chrome浏览器打开"打开上次关闭的标签"设置.其中一个页面上有一个表单(例如登录),然后用户在某个时刻退出浏览器.他第二天重新打开浏览器(12小时过去,因此会话cookie和会话数据已过期)Chrome尝试重新加载所有打开的页面.它向服务器发送两个同时发出的请求,而它们都没有会话cookie.在服务器端,Laravel为每个会话ID生成两个不同的会话ID.Chrome接收它们并覆盖其他会话cookie上的一个.一旦用户尝试提交表单(例如登录),它就会在表单会话cookie被覆盖时生成CSRF错误.
我们还有一些AJAX帖子请求,由于这种情况我们失败了CSRF错误.
我想知道Laravel是否能够以安全的方式为两个请求生成相同的会话ID.
有没有人有任何想法我们如何解决这个问题?
PS:我们正在使用laravel 4.1和这个会话配置:
return array(
'driver' => 'redis',
'lifetime' => 720,
'expire_on_close' => false,
'files' => storage_path().'/sessions',
'connection' => null,
'table' => 'sessions',
'lottery' => array(2, 100),
'cookie' => 'laravel_session',
'path' => '/',
'domain' => '.ourdomain.com',
);
Run Code Online (Sandbox Code Playgroud)
Ami*_*mir 15
经过我们公司对这个问题的大量调查,我得出了这个结果,我希望它有所帮助,首先这里是我们的环境规范:
首先,似乎TokenMistmatch异常发生在各种不同的条件下,我几乎调查了所有这些异常,并且能够解决其中的一些,一些取决于会话背后的逻辑,一些可能是错误.在下文中,我将解释我面临的每种情况.
1.过期会议
假设您已经将会话配置为3个小时,用户打开表单并出于某种原因离开计算机(获得一杯咖啡),因此在会话过期3小时后,他尝试提交表单并获取令牌例外.这就是为什么每个人一旦进入同时获得令牌错误而不管应用程序有多稳定,我可以想象有两种方法可以防止它并且他们使用ajax及时更新会话cookie,或者增加会话到期时间相当长的时间.
2.会话过期时的并发请求
有时在第一页的加载时发生并发请求,例如用户在chrome上打开了两个不同的选项卡,当他重新打开时,chrome chrome会同时发送请求,或者您可能在第一页的加载时有多个并发的ajax请求应用.所以请注意,会话cookie是在收到第一个响应后收到的,但您可以在此之前发送下一个请求,因此您将在每个请求上获得一个新会话(新cookie),这可能会导致令牌异常,如果其中一个请求填充表单.您可以根据它的源来阻止这种情况,例如,如果ajax请求导致问题并且您没有在ajax响应中使用会话,则可以在第二种情况下禁用发送会话cookie(如果请求是ajax)(单击多次提交按钮)一旦提交,您可以简单地禁用该按钮.
3.登录时的并发请求
当登录发生时,出于安全原因,laravel会更改会话ID,复制会话数据和DESTROYS THE LAST SESSION,因此在登录并发请求时会出于某种原因说(多次单击登录按钮),以便重新生成会话ID多次和DESTROYS在服务器端最后生成的会话,因为其中一些请求仍然使用先前的会话ID(在服务器端不再存在)它导致重新生成CSRF令牌,请注意通常laravel不如果可以在guest虚拟机(未登录)会话中找到令牌,则在登录时重新生成令牌,但在这种情况下,因为guest虚拟机会话被销毁,因此它将重新生成令牌,并且可能导致其他请求中的令牌异常使用原始令牌.另请注意,此问题不仅会导致令牌异常,还会导致用户在一次请求后被注销,因为并发请求可以更改登录的会话.我通过更改laravel代码中的一行来解决此问题Illuminate\Auth\Guard:updateSession:
protected function updateSession($id)
{
$this->session->put($this->getName(), $id);
//$this->session->migrate(true);
$this->session->migrate()
}
Run Code Online (Sandbox Code Playgroud)
将true传递给会话存储的migrate方法将导致在迁移后销毁服务器上的会话,因此现在数据将保留在服务器上并在其到期时间而不是在此请求上销毁,它将解决问题.我不知道我们是否可以将其称为laravel中的错误,但我想我们可以为此提出更好的解决方案.
4.浏览器
调查日志后发现,其中一些令牌异常是因为用户的浏览器不接受会话cookie,我在iOS Safari上看到的最多,我相信这是我们无能为力的事情.
5. Redis bug
我们服务器上的一些令牌例外是因为redis,因为某些原因,laravel在打开会话时无法从redis服务器读取会话数据,因此会导致CSRF令牌的重新生成.它是在我们的服务器上随机发生的,所以我尝试更改会话驱动程序,这种类型的异常逐渐消失.我尝试过数据库,apc和文件驱动程序,没有人产生这个问题.我还没有找到导致错误的原因,但我认为它可能是redis或predis库的错误.(如您所知,由于兼容性问题,laravel 4.1未使用最新版本的predis).
好的,这是我过去两个月在这个问题上的经历.我希望它可能改变你对这个问题的解决方案的观点,最重要的是令牌异常不会发生,因为一个原因可能是多个问题的结果.如果您遇到类似事件或者您有新事物,请与我分享.
| 归档时间: |
|
| 查看次数: |
7817 次 |
| 最近记录: |