4

In twig i generate a csrf token ({{ csrf_token('my_intention') }}).

In Javascript i call a controller with ajax, in fact with the Fetch API (Ajax xmlHttpRequest tried too), POST request. Argument name containing the token passed in the request is 'token=abcdef...'.

AJAX:

    var httpRequest = new XMLHttpRequest();
    httpRequest.onreadystatechange = function (data) {
        console.log(data);
    };

    httpRequest.open('POST', el.getAttribute("data-url"));
    httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    httpRequest.send(.......);

Fetch API:

        fetch(el.getAttribute('data-url'), {
            method: 'post',
            headers: {
                "Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
            },
            body: 'token=' + encodeURIComponent(el.getAttribute('data-token'))
        }).then(data => data.text()).then(data => {...}

In the controller action called i get the token sent as data from the POST request. I check the token like this in the controller:

    $token = $request->request->get('token');
    if (!$this->isCsrfTokenValid('my_intention', $token)) {
        throw new InvalidCsrfTokenException("error csrf 2");
    }

But Symfony say the token is not valid.

I'm not sure but i think token is not found in session variable. In isTokenValid() $this->storage->hasToken($token->getId()) return false.

In the browser, if i call the url directly, it's ok.

In twig i set the url to call in a data attribute like this data-url="{{ path('_check', {'id': transaction.id}) }}", then i read this data attribute from javascript and pass it to ajax/fetch function.

I tried ajax with jQuery $.post(... and it works. The only difference is Cookie:PHPSESSID... in the request header with jQuery not on my original code.

I don't understand, what is wrong with my code ?

Symfony 3.1.3

EDIT: resolved: i didn't pass credentials in headers request, so, no way for Symfony to find session and check token:

    fetch(el.getAttribute('data-url'), {
        method: 'post',
        headers: {
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
            "X-Requested-With": "XMLHttpRequest"
        },
        body: 'token=' + el.getAttribute('data-token'),
        credentials: 'include'
    }).then(data => data.text()).then(data => {

1 Answer 1

2

Even if you found an answer to your issue, I recommend you to take a look at this bundle which handles the token verification based on a Cookie which is defined server-side and that you should pass in each asynchronous request.

https://github.com/dunglas/DunglasAngularCsrfBundle

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.