My jquery AJAX POST requests works without sending an Authenticity Token (Rails)

 ̄綄美尐妖づ 提交于 2019-12-04 07:06:20

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).

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.

Add this in your layout view: app/views/layouts/(something).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 :

$.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:

 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.

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.

Hope this helps! Cheers :)

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