I am using Symfony2.0 and FOSUserBundle, and would like to disable the csrf token on my login form.
I have disabled the csrf protection globally on my website in my config.yml:
framework:
csrf_protection:
enabled: false
This is working well, there is no csrf field added to my forms.
However, this does not apply to the login form. On this form only, I get an "Invalid CSRF Token" error if I don't include the token in the form with:
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}" />
How can I disable the CSRF token on the login form?
If you just go to your security.yml file and remove the csrf_provider from the form_login directive, don't need to update the action class or anything.
You can disable CSRF protection in your form class by setting 'csrf_protection' => false
in its options array:
class LoginType extends AbstractType
{
// ...
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'Acme\UserBundle\Entity\User',
'csrf_protection' => false
);
}
// ...
}
In case you are using FormBuilder to create your form instead of an AbstractType class, you can pass the options array as the second parameter for createFormBuilder()
like this:
$form = $this->createFormBuilder($users, array('csrf_protection' => false))
->add( ... )
->getForm();
if you're using FOSUserBundle, and you would like to disable CSRF protection only on the login form, there are a few steps to follow.
Step 1) Create your own user bundle & Security Controller file
In order to over-ride the SecurityController that is built into FOSUserBundle, you must first create your own user bundle.
So, create a file called app/src/{YourApp}/UserBundle/Controller/SecurityController.php
You should extend the original SecurityController class, and copy over the loginAction method
use FOS\UserBundle\Controller\SecurityController as SecurityControllerOrig;
class SecurityController extends SecurityControllerOrig
{
public function loginAction(Request $request)
{
}
}
Within the loginAction method, comment out, or remove these lines:
$csrfToken = $this->container->has('form.csrf_provider')
? $this->container->get('form.csrf_provider')->generateCsrfToken('authenticate')
: null;
Then make sure that nothing is passed to view for the CSRF token:
return $this->renderLogin(array(
'last_username' => $lastUsername,
'error' => $error,
'csrf_token' => false,
));
Step 2) Disable CSRF checking in Symfony's firewall (security.yml)
Make sure you comment out the existing "csrf_provider:" line in security.yml:
firewalls:
main:
pattern: ^/
form_login:
provider: fos_userbundle
#csrf_provider: form.csrf_provider
Step 3) Override the routing for FOSUserBundle's security controller (routing.yml)
In routing.yml, comment out these lines:
fos_user_security:
resource: "@FOSUserBundle/Resources/config/routing/security.xml"
options:
expose: true
Add these lines below the commented-out lines:
#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
Note 1: I've only asked it to use the loginAction method from your custom SecurityController. The other two methods go to the parent class (not sure if it makes a difference).
Note 2: You need the "expose: true" part! Otherwise, you'll get a JavaScript error from the fos js routing bundle.
That should do it!
I had to override FOSUserBundle's SecurityController loginAction where the login form is instanciated.
I replaced:
$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,
));
with:
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,
));