9

I have CSRF enabled on my install. I have a bunch of frontend forms so CSRF is pretty important for me. However, when I use AJAX to post to a controller action I get the following error.

<div id="message" class="pane">
    <h2>Bad Request</h2>
    <p>The CSRF token could not be verified.</p>
</div>

Here is my AJAX that I am testing with.

$(function(){
    var data = { id: 100 };
    $.post("/actions/gistClient/exampleAjax", data, function(response) {
        console.log("success", response, data);
    });
});

Here is my controller action

public function actionExampleAjax()
{
    $this->requireAjaxRequest();
    // ... whatever your AJAX does...
    $response = array('response' => 'Round trip via AJAX!');
    $this->returnJson($response);
}

Is it possible to disable CSRF for certain routes? Alternatively, how would I pass CSRF through AJAX to the controller action?

2 Answers 2

21

Disabling the CSRF protection is probably a bad idea... it's in there for a reason. But you can easily add your CSRF data to an AJAX call, and it works very well!

The key is to make your CSRF token name & value available in your front-end JS. You can then pass that into your AJAX call as an additional value.

There are a few ways to push the CSRF data to the front-end, so this is simply one example:

{% set csrfToken = {
    csrfTokenName: craft.app.config.general.csrfTokenName,
    csrfTokenValue: craft.app.request.csrfToken,
} %}

<script type="text/javascript">
    window.Craft = {{ csrfToken|json_encode|raw }};
</script>

Once you've got those values on the front-end, adding them to your AJAX call is relatively easy:

$(function(){
    var data = { id: 100 };
    data[window.Craft.csrfTokenName] = window.Craft.csrfTokenValue; // Append CSRF Token
    $.post("/actions/gistClient/exampleAjax", data, function(response) {
        console.log("success", response, data);
    });
});

That's it! Your AJAX call should now submit properly.

1
10

This is the syntax for Craft 3:

<script type="text/javascript">
    window.csrfTokenName = "{{ craft.app.config.general.csrfTokenName }}";
    window.csrfTokenValue = "{{ craft.app.request.csrfToken }}";
</script>

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.