Proper way to send an Authenticity Token with AJAX to Rails

冷暖自知 提交于 2019-11-28 04:53:18

Actually, you are reading the action attribute of form and sending a post ajax request to it. to send form data you have to submit the form or you can serialize the form data and send it in ajax request like

$(".ajax-referral").click(function(){
  $.ajax({
      type: "POST", 
      url: $(this).parent("form").attr("action") + "?&authenticity_token=" + AUTH_TOKEN, 
      data:$(this).parent("form").serialize(),
      dataType: "script"
      });
  return false;
});

Doing this will serialize your form data and send it along with ajax request and authenticity token is already being sent via query string

This token also already appears in one of the "meta" tags in the head of the application.html.erb layout file by default if you have the following ERB at the top:

<%= csrf_meta_tag %>

That ERB roughly renders to:

<meta content="abc123blahblahauthenticitytoken" name="csrf-token">

You can then grab it using jQuery with the following code:

var AUTH_TOKEN = $('meta[name=csrf-token]').attr('content');

None of these worked for me until I set the X-CSRF-Token value on the request header via JS like this:

request.setRequestHeader('X-CSRF-Token', token)

token of course, being the CSRF token. I got this from the <meta name="csrf-token"> tag and did not use encodeURIComponent()

Update since this is proving useful to some

So all in all:

var token = document.querySelector('meta[name="csrf-token"]').content
request.setRequestHeader('X-CSRF-Token', token)

Thanks!

Just to clarify for the more common use.

You need the js tag with var AUTH_TOKEN in your head. Should be something like this.

<%= csrf_meta_tag %>
<%= javascript_tag "var AUTH_TOKEN = '#{form_authenticity_token}';" if protect_against_forgery? %>

And then simply put your authenticity_token=AUTH_TOKEN in the ajax data if you don't need to use parent(form) or something like this.

$.ajax({
  type: 'post',
  dataType:'text',
  data: "user_id="+user_id+"&authenticity_token="+AUTH_TOKEN,
  url:'/follow/unfollow'
})

Thanks to the guys above for sharing this knowledge!

You could include the AUTH_TOKEN in the form itself, as a hidden input.

<input type="hidden" name="AUTH_TOKEN">1234abcd</input>
carnator

I just ran into this issue but I tried this approach in my application.js file:

$(document).ajaxSend(function(e, xhr, options) {
  if (options.data == null) {
    options.data = {};
  }
  options.data['authenticity_token'] = token;
});

This is the original question where I got the idea: ajaxSend Question

Simply using form_tag automatically includes CSRF token parameter. Rails supports "Unobtrusive Javascript" meaning that the form will still be submitted via AJAX. Controller actions support "respond_to" block, and you can use .js.erb extension to make changes on the web page in response to form submit.

In Rails 5.1+ a CSRF token is automatically appended if you use a built-in Rails JS helper for AJAX requests(from rails-ujs), example:

Rails.ajax({
  url: "/your/url",
  type: "POST",
  data: "a=1&b=2",
  success: function(data) {
    console.log(data);
  }
});

This library also provides you a helper to get CSRF token manually if you need it with:

Rails.csrfToken();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!