我的jquery AJAX POST请求在不发送真实性令牌(Rails)的情况下工作

时间:2022-10-09 11:42:31

Is there any provisions in rails that would allow all AJAX POST requests from the site to pass without an authenticity_token?

rails中是否有允许站点上的所有AJAX POST请求在没有authenticity_token的情况下通过的条款?

I have a Jquery POST ajax call that calls a controller method, but I did not put any authenticity code in it and yet the call succeeds.

我有一个Jquery POST ajax调用,它调用一个控制器方法,但是我没有在其中放入任何真实性代码,但是调用成功了。

My ApplicationController does have 'request_forgery_protection' and I've changed

我的ApplicationController确实有“request_forgery_protection”,我已经更改了

config.action_controller.consider_all_requests_local

to false in my environments/development.rb

在我的环境/开发中出错

I've also searched my code to ensure that I was not overloading ajaxSend to send out authenticity tokens.

我还搜索了代码,以确保没有重载ajaxSend发送真实性令牌。

Is there some mechanism in play that disables the check? Now I'm not sure if my CSRF protection is working or not.

有什么机制可以阻止支票吗?现在我不确定我的CSRF保护是否有效。

I'm using Rails 2.3.5.

我使用Rails 2.3.5。

Update for clarity:

更新清晰:

function voteup(url, groupid){
      $.ajax({
        type: "POST",
        url: "/groups/" + groupid + "/submissions/voteup",
        data: "url=" + url,
        dataType: 'text',
        success: function(data){
          var counter = "vote_" + url;
          $('#vote_' + url.cleanify()).text(" " + data + " ");
        }
      });
    };

I have a link which then has a 'href that calls the above function:

我有一个链接,它有一个href来调用上面的函数:

<a href='javascript:voteup(param1,param2)'>...</a>

3 个解决方案

#1


6  

A likely scenario here is that you're using jQuery to serialize a normal Rails form... and it is including in that the serialized auth token hidden field (Rails adds them to all forms).

一个可能的情况是您正在使用jQuery来序列化一个普通的Rails表单……它包括序列化的auth令牌隐藏字段(Rails将它们添加到所有表单中)。

Look at your generated source for the form you're submitting... it's likely you'll see

查看您提交的表单的生成源……很有可能你会看到

<input name="authenticity_token" type="hidden" value="somethinghere...." />

The other thing you can do is check the log to see if the authenticity_token field is in the request params.

您可以做的另一件事是检查日志,看看authenticity_token字段是否在request params中。

#2


3  

Add this in your layout view: app/views/layouts/(something).html.erb

在布局视图中添加这个:app/view /layout /(某物).html.erb

<% if protect_against_forgery? %>
 <script type="text/javascript" charset="utf-8">
  //<![CDATA[
   window._auth_token_name = "#{request_forgery_protection_token}";
   window._auth_token = "#{form_authenticity_token}";
  //]]>
 </script>
<% end %>

And in your application.js :

在您的应用程序。js:

$.ajaxSetup({
  'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
});

$(document).ready(function() {
 //  All non-GET requests will add the authenticity token
 //  If not already present in the data packet
 $("body").bind('ajaxSend', function(elm, xhr, s) {
   if (s.type == "GET") return;
   if (s.data && s.data.match(new RegExp("\\b" + window._auth_token_name + "="))) return;
   if (s.data) {
  s.data = s.data + "&";
  } else {
   s.data = "";
   // if there was no data, $ didn't set the content-type
   xhr.setRequestHeader("Content-Type", s.contentType);
  }
  s.data = s.data + encodeURIComponent(window._auth_token_name) + "=" + encodeURIComponent(window._auth_token);
 });

In your application_controller.rb add this to ensure IE/SAFARI receive correct accept headers:

在你application_controller。rb添加这个以确保IE/SAFARI接收正确的接收头:

 def correct_safari_and_ie_accept_headers
    ajax_request_types = [ 'text/javascript', 'application/json', 'text/xml']
        request.accepts.sort!{ |x, y| ajax_request_types.include?(y.to_s) ? 1 : -1 } if request.xhr?
 end

This ensures that the accept header default to text/javascript, application/json or text/xml instead of the default text/html.

这确保accept标头默认为文本/javascript、应用程序/json或文本/xml,而不是默认的文本/html。

Now you can perform your regular AJAX calls. It will pass the auth token. Also make sure you include application.js only after the CDATA script tag as it requires the two global vars window._auth_token_name and window._auth_token.

现在可以执行常规的AJAX调用。它将传递auth令牌。还要确保包含应用程序。仅在CDATA脚本标记之后,它需要两个全局vars窗口。_auth_token_name window._auth_token。

Hope this helps! Cheers :)

希望这可以帮助!欢呼:)

#3


0  

I have a similar question and I believe I found a partial answer:

我有一个类似的问题,我相信我找到了部分答案:

Rails 3 AJAX request authenticity token ignored

Rails 3 AJAX请求真实性令牌被忽略

#1


6  

A likely scenario here is that you're using jQuery to serialize a normal Rails form... and it is including in that the serialized auth token hidden field (Rails adds them to all forms).

一个可能的情况是您正在使用jQuery来序列化一个普通的Rails表单……它包括序列化的auth令牌隐藏字段(Rails将它们添加到所有表单中)。

Look at your generated source for the form you're submitting... it's likely you'll see

查看您提交的表单的生成源……很有可能你会看到

<input name="authenticity_token" type="hidden" value="somethinghere...." />

The other thing you can do is check the log to see if the authenticity_token field is in the request params.

您可以做的另一件事是检查日志,看看authenticity_token字段是否在request params中。

#2


3  

Add this in your layout view: app/views/layouts/(something).html.erb

在布局视图中添加这个:app/view /layout /(某物).html.erb

<% if protect_against_forgery? %>
 <script type="text/javascript" charset="utf-8">
  //<![CDATA[
   window._auth_token_name = "#{request_forgery_protection_token}";
   window._auth_token = "#{form_authenticity_token}";
  //]]>
 </script>
<% end %>

And in your application.js :

在您的应用程序。js:

$.ajaxSetup({
  'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
});

$(document).ready(function() {
 //  All non-GET requests will add the authenticity token
 //  If not already present in the data packet
 $("body").bind('ajaxSend', function(elm, xhr, s) {
   if (s.type == "GET") return;
   if (s.data && s.data.match(new RegExp("\\b" + window._auth_token_name + "="))) return;
   if (s.data) {
  s.data = s.data + "&";
  } else {
   s.data = "";
   // if there was no data, $ didn't set the content-type
   xhr.setRequestHeader("Content-Type", s.contentType);
  }
  s.data = s.data + encodeURIComponent(window._auth_token_name) + "=" + encodeURIComponent(window._auth_token);
 });

In your application_controller.rb add this to ensure IE/SAFARI receive correct accept headers:

在你application_controller。rb添加这个以确保IE/SAFARI接收正确的接收头:

 def correct_safari_and_ie_accept_headers
    ajax_request_types = [ 'text/javascript', 'application/json', 'text/xml']
        request.accepts.sort!{ |x, y| ajax_request_types.include?(y.to_s) ? 1 : -1 } if request.xhr?
 end

This ensures that the accept header default to text/javascript, application/json or text/xml instead of the default text/html.

这确保accept标头默认为文本/javascript、应用程序/json或文本/xml,而不是默认的文本/html。

Now you can perform your regular AJAX calls. It will pass the auth token. Also make sure you include application.js only after the CDATA script tag as it requires the two global vars window._auth_token_name and window._auth_token.

现在可以执行常规的AJAX调用。它将传递auth令牌。还要确保包含应用程序。仅在CDATA脚本标记之后,它需要两个全局vars窗口。_auth_token_name window._auth_token。

Hope this helps! Cheers :)

希望这可以帮助!欢呼:)

#3


0  

I have a similar question and I believe I found a partial answer:

我有一个类似的问题,我相信我找到了部分答案:

Rails 3 AJAX request authenticity token ignored

Rails 3 AJAX请求真实性令牌被忽略