Login Form: Adding a CSRF Token

Come back soon - still in progress!

Leave a comment!

  • 2016-05-17 Yoni L.

    Hi, it works without!! i followed the official doc and as it was writtten i put it. So the csrf_token_generator config doesn't do anything...

  • 2016-05-13 weaverryan

    Thanks for sharing your result Yoni! And nice work! You might *not* need the csrf_token_generator config under form_login in security.yml. That's the only part I wasn't sure about - that looks unnecessary to me, but I'm not sure!

  • 2016-05-12 Yoni L.

    i managed to add the csrf protection with the infos of your commit! only pass the @security.csrf.token_manager service to the constructor or get the service if you pass all the container, it's quite easy and is not much more complicated than the simple form type;
    for example:

    in your services.yml:

    class: AppBundle\Security\FormLoginAuthenticator
    arguments: ["@doctrine.orm.default_entity_manager", "@security.password_encoder", "@router", "@security.csrf.token_manager"]

    in your form add the following in your <form>:

    <input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">

    the "authenticate" is a key to retrieve this specific token, it could be anything else but authenticate is obvious...

    in your security.yml, add:

    csrf_token_generator: security.csrf.token_manager

    Your FormLoginAuthenticator class constructor may seems like that:
    Don't forget the attributes and the use statement !

    use Symfony\Component\Routing\RouterInterface;
    use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
    use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
    use Symfony\Component\Security\Core\Security;
    use Symfony\Component\Security\Core\User\UserInterface;
    use Symfony\Component\Security\Core\User\UserProviderInterface;
    use Symfony\Component\Security\Csrf\CsrfToken;
    use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
    * @var RouterInterface
    private $router;

    * @var UserPasswordEncoderInterface
    private $passwordEncoder;

    * @var EntityManagerInterface
    private $entityManager;

    * @var CsrfTokenManagerInterface
    private $csrfTokenManager;

    public function __construct(EntityManagerInterface $entityManager, UserPasswordEncoderInterface $passwordEncoder, RouterInterface $router, CsrfTokenManagerInterface $csrfTokenManager) {
    $this->entityManager = $entityManager;
    $this->passwordEncoder = $passwordEncoder;
    $this->router = $router;
    $this->csrfTokenManager = $csrfTokenManager;

    Finally in your getCredential (or checkCredentials but if you do so don't forget to add the csrf key in the return array of getCredentials), add the csrf control:

    $csrfToken = $request->get('_csrf_token');
    if ($this->csrfTokenManager->isTokenValid(new CsrfToken('authenticate', $csrfToken)) === false) {
    throw CustomAuthenticationException::createWithSafeMessage(
    _('Accès non autorisé')
  • 2016-05-07 weaverryan

    Sorry Jon :). This is a free tutorial, and it got a bit side-tracked when we got Guard accepted into core.

    If it helps, I *do* have the code for doing this (at least with the bundle). Check out the finished branch here: https://github.com/knpunive.... Specifically, this is the commit for CSRF: https://github.com/knpunive...

    I hope that helps :)

  • 2016-05-06 Jon Chapman

    arrrghhh....nine months later....

  • 2015-08-20 weaverryan

    Oh oh oh, I misunderstood entirely! You're totally right - great point. You're re-using the built-in CSRF protection in the form system - I like it!

  • 2015-08-20 Neandher Carlos

    I'm using GUARD, but I created a form type login logging by email:


    -> add ('email', 'email')
    -> add ('password', 'password');


    {{form_label (form.email, 'Email')}}
    {{form_widget (form.email, {'attr': {'value': last_username}})}}
    {{form_label (form.password, 'Password')}}
    {{form_widget (form.password)}}
    {{ form_widget(form._token) }}


    $email = $ request->request->get('login')['email'];
    $request->getSession()->set(Security :: LAST_USERNAME, $email);

    $password = $ request->request->get ('login') ['password'];

  • 2015-08-20 weaverryan

    It's easier, but less flexible actually - you have much more control with Guard (which is why it's also not as easy). Both are good options - depends on your needs :)

  • 2015-08-20 Neandher Carlos

    It is much more flexible to create a form type login. It comes with CSRF token. http://symfony.com/doc/curr...

  • 2015-07-23 Jason Simmons

    Temporary solution perhaps. Build into your login form view and make it part of you credentials check. Should work this is what I will try myself.