Symfony 4 - how to add csrf token without building form?
Asked Answered
S

5

13

I am reading tutorial here

https://symfony.com/doc/current/form/csrf_protection.html

how to add csrf token. It says to use

form_end()

in the template. But this is not working, gives error:

Type error: Too few arguments to function Symfony\Component\Form\FormRenderer::renderBlock(), 0 passed in E:\projektai\php projektai\htdocs\mokomieji\symfony_4_demo\var\cache\dev\twig\bb\bb2248f7be504240fcc2ab43dabf593090ebc4c897ce72b1a979082d62914b47.php on line 48 and at least 2 expected

Here is answer which shows how to fix but it is only when you have form object built:

Symfony Type error: Too few arguments to function FormRenderer::renderBlock()

How to do this without having form object? Here is login from login documentation page:

{% if error %}
    <div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}

<form action="{{ path('login') }}" method="post">
    <label for="username">Username:</label>
    <input type="text" id="username" name="_username" value="{{ last_username }}" />

    <label for="password">Password:</label>
    <input type="password" id="password" name="_password" />

    <button type="submit">Login</button>

{{  form_end() }}
Spense answered 18/12, 2017 at 15:56 Comment(0)
B
20

You can use the helper twig function csrf_token as described in the doc here, as example:

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

More help in this answer.

UPDATE:

Other strategy: pass from controller:

    $tokenProvider = $this->container->get('security.csrf.token_manager');
    $token = $tokenProvider->getToken('example')->getValue();

Hope this help

Backache answered 18/12, 2017 at 16:6 Comment(2)
This does give error: An exception has been thrown during the rendering of a template ("CSRF tokens can only be generated if a CsrfTokenManagerInterface is injected in FormRenderer::__construct().").Spense
what is "example" stand for in gettoken?Maryannemarybella
A
11

You can use {{ form_row(form._token) }} to generate the required CSRF token field to your form render in Symfony 3 (i'm currenlty use this method with Symfony 3.4).

Aurita answered 28/3, 2018 at 14:56 Comment(0)
C
4

{{ form_end() }} works only if you have something like this:

{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}

You can create custom token in your controller and then pass it to the view like this:

    $csrf = $this->container->get('security.csrf.token_manager');
    $token = $csrf->refreshToken('yourkey');

And then create hidden input in your twig with token:

<input type="hidden" name="_token" value="{{ token }}">
Crash answered 18/12, 2017 at 16:5 Comment(0)
F
0

To get the right csrf_token you should create the FormView with $form->createView(), then use the token inside it:

<input type="hidden" name="_token" value="{{ form._token.vars.value }}">

All the other solutions rely on generating a static string that does not change, which violates the purpose of the csrf tokens.

Flavor answered 17/6, 2019 at 14:3 Comment(0)
I
0

For those who are looking for how to generate CSRF tokens inside your Controller methods:

    public function myMethod (
        CsrfTokenManagerInterface $csrfTokenManager
    ): JsonResponse
    {
        // validate token
        // $csrf_token = new CsrfToken('my_token', 'generated_token_value_here');
        // if(!$csrfTokenManager->isTokenValid($csrf_token)) {
        //     //failed. do something.
        //     return new JsonResponse();
        // }
        
        // generate token
        $token = $csrfTokenManager->getToken('my_token')->getValue();
        
        // refresh token
        // $csrfTokenManager->refreshToken('my_token');
        
        return new JsonResponse([
            "token'" => $token
        ]);
    }
Intromit answered 7/9, 2023 at 0:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.