使用AJAX发送真实性令牌的正确方法..?

Tri*_*rip 38 javascript ajax jquery ruby-on-rails authenticity-token

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

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

所以我试着像这样添加它:

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

并且它正确地将auth_token作为参数传递,但似乎丢失了我的表单的其余部分.

无论如何既可以完成发送有效的表单数据,也可以完成真实性令牌?

这是一个rails环境.而且我脑子里有这个.

= javascript_tag "var AUTH_TOKEN = '#{form_authenticity_token}';" if protect_against_forgery?
Run Code Online (Sandbox Code Playgroud)

我尝试过的事情

1.

= hidden_field :authenticity_token, :value => form_authenticity_token
Run Code Online (Sandbox Code Playgroud)

2.

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

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 );
    }
});
Run Code Online (Sandbox Code Playgroud)

Muh*_*hid 32

实际上,您正在阅读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;
});
Run Code Online (Sandbox Code Playgroud)

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

  • 我不得不使用encodeURIComponent(AUTH_TOKEN),但是在我执行此操作后,在查询字符串中使用它. (7认同)
  • 令牌不应在网址中发送! (2认同)

omd*_*del 31

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

<%= csrf_meta_tag %>
Run Code Online (Sandbox Code Playgroud)

ERB大致呈现:

<meta content="abc123blahblahauthenticitytoken" name="csrf-token">
Run Code Online (Sandbox Code Playgroud)

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

var AUTH_TOKEN = $('meta[name=csrf-token]').attr('content');
Run Code Online (Sandbox Code Playgroud)


Ada*_*ant 20

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

request.setRequestHeader('X-CSRF-Token', token)
Run Code Online (Sandbox Code Playgroud)

token当然,作为CSRF令牌.我从<meta name="csrf-token">标签中得到了这个并没有使用encodeURIComponent()

更新,因为这证明对一些人有用

总而言之:

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


小智 15

谢谢!

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

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

<%= csrf_meta_tag %>
<%= javascript_tag "var AUTH_TOKEN = '#{form_authenticity_token}';" if protect_against_forgery? %>
Run Code Online (Sandbox Code Playgroud)

然后,如果您不需要使用父(表单)或类似的东西,只需将您的authenticity_token = AUTH_TOKEN放在ajax数据中.

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

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

  • 身份验证令牌是 base64 编码的。它可能包含一个加号 (+)。如果您没有正确转义 auth 令牌,由于 url 编码,rails 会将其解析为空格。 (2认同)

Rus*_*nov 6

在 Rails 5.1+ 中,如果您Rails对 AJAX 请求(来自rails-ujs)使用内置JS 助手,则会自动附加 CSRF 令牌,例如:

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

如果您需要,该库还为您提供了一个帮助程序来手动获取 CSRF 令牌:

Rails.csrfToken();
Run Code Online (Sandbox Code Playgroud)