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

grz*_*hoo 20 symfony

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

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

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

我不想禁用CSRF保护.

Vit*_*ian 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);
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)


Boh*_*rov 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);
Run Code Online (Sandbox Code Playgroud)