21

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

问题是,如果用户正在填写表单并被注销,在使用 JS 层重新登录后,他仍在查看具有他已经设法输入的值的相同表单,但他的会话发生了变化。因此表单中的 CSRF 令牌无效。

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

我不想禁用 CSRF 保护。

4

4 回答 4

34

假设您使用默认的 CSRF Provider,在您的 AJAX 控制器中,您可以获得您的 CSRF Provider 服务并“要求”它重新生成令牌:

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);
于 2012-07-24T14:10:33.933 回答
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);
于 2014-05-14T15:03:44.447 回答
4

是的,机器人可以获取一个 csrf 令牌并将某些内容发布到表单中,但是由于令牌绑定到会话,所以没关系。CSRF 令牌并非旨在阻止机器人提交表单。

于 2014-10-23T19:52:50.797 回答
1

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

于 2012-07-13T08:36:04.780 回答