我正在使用Symfony2.0和FOSUserBundle,并希望在我的登录表单上禁用csrf令牌。
我在config.yml上的网站上全局禁用了csrf保护:
framework:
csrf_protection:
enabled: false
这很好用,我的表单中没有添加csrf字段。 但是,这不适用于登录表单。仅在此表单上,如果我在表单中不包含令牌,则会收到“无效的CSRF令牌”错误:
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}" />
如何在登录表单上禁用CSRF令牌?
答案 0 :(得分:29)
您可以通过在其选项数组中设置'csrf_protection' => false
来禁用表单类中的CSRF保护:
class LoginType extends AbstractType
{
// ...
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'Acme\UserBundle\Entity\User',
'csrf_protection' => false
);
}
// ...
}
如果您使用FormBuilder创建表单而不是AbstractType类,则可以将options数组作为createFormBuilder()
的第二个参数传递,如下所示:
$form = $this->createFormBuilder($users, array('csrf_protection' => false))
->add( ... )
->getForm();
答案 1 :(得分:18)
如果您只是转到security.yml文件并从form_login指令中删除csrf_provider,则无需更新操作类或任何内容。
答案 2 :(得分:1)
如果您使用的是FOSUserBundle,并且只想在登录表单上禁用CSRF保护,则需要执行几个步骤。
步骤1)创建您自己的用户捆绑包&amp;安全控制器文件
为了覆盖内置于FOSUserBundle中的SecurityController,您必须首先创建自己的用户包。
因此,创建一个名为app / src / {YourApp} /UserBundle/Controller/SecurityController.php的文件 您应该扩展原始的SecurityController类,并复制loginAction方法
use FOS\UserBundle\Controller\SecurityController as SecurityControllerOrig;
class SecurityController extends SecurityControllerOrig
{
public function loginAction(Request $request)
{
}
}
在loginAction方法中,注释掉或删除这些行:
$csrfToken = $this->container->has('form.csrf_provider')
? $this->container->get('form.csrf_provider')->generateCsrfToken('authenticate')
: null;
然后确保没有任何内容传递给CSRF令牌的视图:
return $this->renderLogin(array(
'last_username' => $lastUsername,
'error' => $error,
'csrf_token' => false,
));
步骤2)在Symfony的防火墙(security.yml)中禁用CSRF检查
请确保在security.yml中注释掉现有的“csrf_provider:”行:
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
#csrf_provider: form.csrf_provider
步骤3)覆盖FOSUserBundle安全控制器的路由(routing.yml)
在routing.yml中,注释掉这些行:
fos_user_security:
resource: "@FOSUserBundle/Resources/config/routing/security.xml"
options:
expose: true
在注释掉的行下方添加以下行:
#Over-ride the SecurityController of the FOSUserBundle:
fos_user_security_login:
path: /login
defaults: { _controller: YourAppUserBundle:Security:login }
methods: [GET]
options:
expose: true
fos_user_security_check:
path: /login_check
defaults: { _controller: FOSUserBundle:Security:check }
methods: [POST]
options:
expose: true
fos_user_security_logout:
path: /logout
defaults: { _controller: FOSUserBundle:Security:logout }
methods: [GET]
options:
expose: true
注1:我只是要求它使用自定义SecurityController中的loginAction方法。另外两个方法转到父类(不确定它是否有所不同)。
注2:您需要“expose:true”部分!否则,您将从fos js路由包中收到JavaScript错误。
应该这样做!
答案 3 :(得分:0)
我必须override FOSUserBundle's SecurityController loginAction登录表单才会实现。
我换了:
$csrfToken = $this->container->get('form.csrf_provider')->generateCsrfToken('authenticate');
return $this->container->get('templating')->renderResponse('FOSUserBundle:Security:login.html.'.$this->container->getParameter('fos_user.template.engine'), array(
'last_username' => $lastUsername,
'error' => $error,
'csrf_token' => $csrfToken,
));
使用:
return $this->container->get('templating')->renderResponse('FOSUserBundle:Security:login.html.'.$this->container->getParameter('fos_user.template.engine'), array(
'last_username' => $lastUsername,
'error' => $error,
'csrf_token' => false,
));