使用AJAX将真实性令牌发送到Rails的正确方法

时间:2011-09-26 20:20:22

标签: javascript jquery ruby-on-rails ajax authenticity-token

这可以工作,但因为缺少真实性令牌而被停止:

$(".ajax-referral").click(function(){
  $.ajax({type: "POST", url: $(this).parent("form").attr("action"), dataType: "script"});
  return false;
});

所以我尝试添加它:

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

它正确地将auth_token作为param传递,但似乎丢失了我的其余部分。

无论如何都要完成发送有效的表单数据和真实性令牌?

这是一个rails环境。我脑子里有这个。

= javascript_tag "var AUTH_TOKEN = '#{form_authenticity_token}';" if protect_against_forgery?

我尝试过的事情

1

= hidden_field :authenticity_token, :value => form_authenticity_token

2

$.ajax({type: "POST", url: $(this).parent("form").attr("action"), dataType: "script", authenticity_token: AUTH_TOKEN});

3

// Always send the authenticity_token with ajax
$(document).ajaxSend(function(event, request, settings) {
    if ( settings.type != 'GET' ) {
        settings.data = (settings.data ? settings.data + "&" : "")
            + "authenticity_token=" + encodeURIComponent( AUTH_TOKEN );
    }
});

8 个答案:

答案 0 :(得分:30)

实际上,您正在阅读表单的action属性并向其发送post ajax请求。要发送表单数据,您必须提交表单,或者您可以序列化表单数据并将其发送到ajax请求中,如

$(".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;
});

执行此操作将序列化您的表单数据并将其与ajax请求一起发送,并且已通过查询字符串发送真实性令牌

答案 1 :(得分:30)

如果您在顶部有以下ERB,则此标记也已默认显示在application.html.erb布局文件头部的“meta”标记之一中:

<%= csrf_meta_tag %>

ERB大致呈现:

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

然后您可以使用jQuery使用以下代码获取它:

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

答案 2 :(得分:20)

在我通过JS在请求标头上设置X-CSRF-Token值之前,这些都不适用于我:

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

token当然是CSRF令牌。我是从<meta name="csrf-token">标记获得的,并没有使用encodeURIComponent()

更新,因为这证明对某些

有用 总而言之:

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

答案 3 :(得分:15)

谢谢!

只是为了澄清更常见的用途。

你的头脑中需要带有var AUTH_TOKEN的js标签。应该是这样的。

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

如果你不需要使用父(表格)或类似的东西,那么只需将你的authenticity_token = AUTH_TOKEN放在ajax数据中。

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

感谢上面的人分享这些知识!

答案 4 :(得分:3)

您可以在表单中包含AUTH_TOKEN作为隐藏输入。

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

答案 5 :(得分:3)

我刚遇到此问题,但我在application.js文件中尝试了这种方法:

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

这是我得到这个想法的原始问题:ajaxSend Question

答案 6 :(得分:0)

简单地使用form_tag会自动包含CSRF令牌参数。 Rails支持&#34; Unobtrusive Javascript&#34;意味着表单仍将通过AJAX提交。控制器动作支持&#34; respond_to&#34;阻止,您可以使用.js.erb扩展名在网页上进行更改以响应表单提交。

答案 7 :(得分:0)

在Rails 5.1+中,如果您对AJAX请求(来自array(1) { ["{"product_id":"]=> array(1) { [""10","9""]=> string(0) "" } } )使用内置的Rails JS帮助器,则会自动附加CSRF令牌,例如:

rails-ujs

如果您需要使用此库,该库还为您提供了一个手动获取CSRF令牌的助手:

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