Rails CSRF AJAX w/ Devise & JavascriptMVC

Posted on November 30, 2011

So I am building a Rails app that uses Devise for authentication. Devise is kind enough to provide AJAX methods out of the box for authentication and user creation. Unfortunately, things weren't working so good. Now, before you say "yeah, yeah you have to include the CSRF token in the AJAX body", I knew that already and I was. Turns out that Devise (or perhaps Warden) also expects the HTTP CSRF header to be set. The specific key is "X-CSRF-Token".

This is all fine and dandy if you happen to have full control over your low-level AJAX calls. In jQuery you can set a beforeSend callback when calling $.ajax and set the xhr header there. But I am using JavacriptMVC, which has its own AJAX methods buried deep in its model code. Fortunately, JMVC leverages jQuery.

While I wasn't able to assign a beforeSend callback to JMVC's ajax methods, I was able to add the beforeSend method to the ajaxSetup routine for jQuery, which means every ajax call will run this callback.

    jQuery.ajaxSetup({
        'beforeSend': function(xhr) {
            var token = $("meta[name='csrf-token']").attr("content");
            xhr.setRequestHeader("X-CSRF-Token", token);
        }
    });

I believe this will probably conflict with using other beforeSend methods with jQuery, but I haven't had a need to use beforeSend since and I'll address merging/patching the methods together when the time comes. Until then, I'm a) including the CSRF token in my headers and b) in the body of my JSON responses. It's working.

comments powered by Disqus