如果用户在使用我的Symfony2应用程序时在后台登出(由于会话过期或其他原因),我已经在屏幕上显示了一个JS层,允许用户立即重新登录并继续使用网站。
问题是,如果用户正在填写表单并注销,在使用JS层重新登录之后,他仍然使用他已设法输入的值来查看相同的表单,但他的会话更改。因此,表单中的CSRF令牌无效。
有没有办法根据当前会话和特定表单生成新的CSRF令牌,通过AJAX抓取并在表单中替换?或者可能有其他解决方案吗?
我不想禁用CSRF保护。
答案 0 :(得分:33)
假设您使用默认的CSRF提供程序,您可以在AJAX控制器中获取CSRF提供程序服务并“请求”它重新生成令牌:
/** @var \Symfony\Component\Form\Extension\Csrf\CsrfProvider\SessionCsrfProvider $csrf */
$csrf = $this->get('form.csrf_provider');
$token = $csrf->generateCsrfToken($intention);
return new Response($token);
/** @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 这样,令牌将以自动方式再次生成 此外,您不会丢失数据输入。