12
votes

In my rails app I'm getting "WARNING: Can't verify CSRF token authenticity" on an ajax post to an api.

app/views/layouts/application.html.haml :

!!!
%html
  %head
    = stylesheet_link_tag "application", :media => "all"
    = javascript_include_tag "application"
    = csrf_meta_tags
  %body
    = yield

ajax post :

$.ajax({ url: '#{card_credits_path}',
 type: 'POST',
 beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', '#{form_authenticity_token}')},
 dataType: "json",
 data: { credit_uri: response.data.uri,
         email: $('#email:hidden').val(),
         name: $('.name').val()
       },
success: function(randomobject) {
   window.location = '/';
   },
error: function(){
   console.log("Card information is wrong!");
   }
});
2
Have you verified the contents of form_authenticity_token? What are the contents?zeantsoi
no I haven't and I'm unsure how to do that. Let me see what I can do.Alain Goldman
No need... you can extract the token value from the appropriate meta tag. I've posted a solution demonstrating how this is done.zeantsoi

2 Answers

17
votes

Assuming you've set the CSRF token using the Rails csrf_meta_tag tag, the request's token will be available in the csrf-token meta tag:

<meta content="u-n-i-q-u-e-t-o-k-e-n" name="csrf-token" />

Since you're using jQuery, you can pass the token to your AJAX request by invoking the following value for the beforeSend key:

function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))}
13
votes

This code is already present in the rails/jquery-ujs, so it is a lot easier to just use that:

 beforeSend: $.rails.CSRFProtection