Written May 31, 2008. Tagged JavaScript, Ruby on Rails, jQuery.
By default, Rails 2 employs protection against CSRF attacks.
What it comes down to is sending an authenticity token (unique per session) along with all non-GET requests as well as all Ajax requests.
I prefer jQuery to Prototype, the JavaScript library that ships with Rails. This is how I made jQuery automagically send the authenticity token along with all Ajax requests.
In my application layout, I stick an authenticity token in a JavaScript variable in the page header:
<%= javascript_tag "var AUTH_TOKEN = #{form_authenticity_token.inspect};" if protect_against_forgery? %>
Then in my application.js
file:
$(document).ajaxSend(function(event, request, settings) {
if (typeof(AUTH_TOKEN) == "undefined") return;
// settings.data is a serialized string like "foo=bar&baz=boink" (or null)
settings.data = settings.data || "";
settings.data += (settings.data ? "&" : "") + "authenticity_token=" + encodeURIComponent(AUTH_TOKEN);
});
ajaxSend
is a global event that is broadcast before every Ajax request. This code adds a handler for that event, that in turn adds the authenticity token to the request data.
This solution was inspired by some code by "Andreas" in an "Err the Blog" comment. Note that if you use $.ajaxSetup({data: …})
, though, you only set default data, that is overwritten if the Ajax request has data of its own. My solution effectively merges the authenticity token into whatever other data is in the request.