Reputation: 489
I'm sending an AJAX request from my rails site to itself (to go from javascript to a controller). Rails refuses to allow the POST unless I supply an authenticity token, so I added one using
<%= csrf_meta_tags %>
and
var AUTH_TOKEN = "<%=j form_authenticity_token %>"
and everything was fine. However, a new customer recently installed the plugin that accesses my site and triggers the AJAX in the first place. But for this one customer--the authenticity token was denied, despite being supplied (I checked in the logs.)
I realize I'm not giving a lot of clues to go off of, but what could cause the authenticity token to be accepted in one situation and denied in another? More broadly, how is the authenticity_token generated anyways--a new one every single time the page is loaded?
Upvotes: 1
Views: 685
Reputation: 102250
Rails assigns a cryptographically random CSRF token to the the user session.
The server compares the value submitted for the authenticity_token
parameter to the value associated with the user’s session.
One thing you especially need to be careful with is that if you are using fragment caching (which speeds up rendering by caching chunks of the view) you need to ensure that your <%= csrf_meta_tags %>
are not cached since a stale csrf meta tag will lead to mismatch with the token stored in the session.
When posting with ajax, you need to forward the CSRF token with the X-CSRF-Token
header.
var promise = $.ajax({
url: '/example',
type: 'POST',
beforeSend: function(xhr) {
xhr.setRequestHeader('X-CSRF-Token',
$('meta[name="csrf-token"]').attr('content'))
},
data: 'someData=' + someData
});
Upvotes: 3