生成新的CSRF令牌而不重新加载整个表单

时间:2012-07-13 08:29:51

标签: symfony

如果用户在使用我的Symfony2应用程序时在后台登出(由于会话过期或其他原因),我已经在屏幕上显示了一个JS层,允许用户立即重新登录并继续使用网站。

问题是,如果用户正在填写表单并注销,在使用JS层重新登录之后,他仍然使用他已设法输入的值来查看相同的表单,但他的会话更改。因此,表单中的CSRF令牌无效。

有没有办法根据当前会话和特定表单生成新的CSRF令牌,通过AJAX抓取并在表单中替换?或者可能有其他解决方案吗?

我不想禁用CSRF保护。

4 个答案:

答案 0 :(得分:33)

假设您使用默认的CSRF提供程序,您可以在AJAX控制器中获取CSRF提供程序服务并“请求”它重新生成令牌:

Symfony 2.3(和之前的)

/** @var \Symfony\Component\Form\Extension\Csrf\CsrfProvider\SessionCsrfProvider $csrf */
$csrf = $this->get('form.csrf_provider');
$token = $csrf->generateCsrfToken($intention); 

return new Response($token);

Symfony 2.4

/** @var \Symfony\Component\Security\Csrf\CsrfTokenManagerInterface $csrf */
$csrf = $this->get('security.csrf.token_manager');
$token = $csrf->refreshToken($intention);

return new Response($token);

答案 1 :(得分:10)

使用它来重新生成CSRF令牌(自Symfony2.4起):

$csrf = $this->get('security.csrf.token_manager'); //Symfony\Component\Security\Csrf\CsrfTokenManagerInterface
$token = $csrf->refreshToken($intention); // Intention is specified in form type

return new Response($token);

答案 2 :(得分:4)

是的,机器人可以获取csrf令牌并向表单发布内容,但由于令牌绑定到会话,因此无关紧要。 CSRF令牌并非旨在阻止机器人提交表格。

答案 3 :(得分:1)

对我而言,更简单的解决方案是在同一表单上重定向用户,通过POST传递数据alredy 这样,令牌将以自动方式再次生成 此外,您不会丢失数据输入。