Check out my new company

MeetSpace Logo MeetSpace: Video conferencing for distributed teams

Backbone and Rails Forgery Protection

by on

I just had a tough time getting Rails 3 to play nice with Backbone JS, and it turned out to be a simple problem with a simple solution. Backbone was not sending the csrf authenticity token embedded in the page when it sent create/update/delete requests, and Rails was destroying the session when it detected the invalid request.

Here is all the javascript it took to get Backbone to include the token with all requests:


/* alias away the sync method */
Backbone._sync = Backbone.sync;

/* define a new sync method */
Backbone.sync = function(method, model, success, error) {
/* only need a token for non-get requests */
if (method == 'create' || method == 'update' || method == 'delete') {
/* grab the token from the meta tag rails embeds */
var auth_options = {};
auth_options[$("meta[name='csrf-param']").attr('content')] =
$("meta[name='csrf-token']").attr('content');
/* set it as a model attribute without triggering events */
model.set(auth_options, {silent: true});
}
/* proxy the call to the old sync method */
return Backbone._sync(method, model, success, error);
}

Note that this depends on the meta tags being present, which require you to call the helper "csrf_meta_tag" in your rails view for the page (put it in the head).

Comments

rubiii
i'd love to hear more about using backbone with rails. i really like backbone, but to me it still feels like i have to write "a lot" of additional code. routes, models and validations for example.

i'm hacking on retrieving these things from rails, but maybe there's a better way to do this?!
Nick Gauthier
I'm going to put together something larger. It may fit in a blog post, but probably not. It may be a talk, I'm not sure yet.

I don't want to do a tutorial. For me, that's not very interesting. I want to write about backbone "6 months in" because that's where I think it will really shine.

So far, my initial impressions are that the code you write on the front end is code that you don't have to write on the back (especially crazy rails view code).

The most amazing part so far has been that if you wire everything up right by embracing event-driven coding, changes cascade to all the right places automatically. That is *huge* for "6 months in" when you can't afford to update an ajax call in 24 places when you change a template.
rubiii
got it. i also love the evented part of backbone!

so how do you do templating? do you load templates upfront (via something like jammit) and then request json data, do you load the templates and the json and rely on caching or do you have rails render the template and retrieve the complete template?

also, did you run any metrics comparing the performance of your app with and without backbone?
Nick Gauthier
jammit + underscore templates + json api.

Benchmarks are tough because it depends heavily on many factors. However, I can tell you that a specifically heavy page went from 10s just for the Rails request, to 0.6s according to chrome's load time. So, speed improvements are massive.

Also, the user's subjective speed is even higher, because we can manipulate elements on the front-end while doing an asynchronous call behind the scenes. So everything is instant :-)
Maciej Adwent
Heya Nick,

Thanks for this code, it really cleared up some initial confusion for me.

I've wrapped your code up in a little github project:

https://github.com/Maciek416/BackboneRailsAuthTokenAdapter
Nick Gauthier
awesome! Thanks for packaging it up nicely!
vijaydev
Thanks a lot!
blog comments powered by Disqus