Правильный способ отправки токена подлинности с AJAX в Rails - PullRequest
38 голосов
/ 27 сентября 2011

Это работает, но останавливается, потому что ему не хватает токена подлинности:

$(".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 в качестве параметра, но, похоже, теряет остальную часть моей формы.

В любом случае для выполнения как отправки данных формы, так и токена подлинности?

Это среда 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 ]

30 голосов
/ 18 ноября 2013

Этот токен также уже появляется в одном из мета-тегов в заголовке файла макета application.html.erb по умолчанию, если у вас есть следующий ERB вверху:

<%= csrf_meta_tag %>

Что ERB примерно отображает:

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

Затем вы можете получить его с помощью jQuery со следующим кодом:

var AUTH_TOKEN = $('meta[name=csrf-token]').attr('content');
30 голосов
/ 27 сентября 2011

На самом деле, вы читаете атрибут 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 и маркером подлинности.уже отправляется через строку запроса

20 голосов
/ 16 марта 2015

Ничто из этого не работало для меня, пока я не установил значение X-CSRF-Token в заголовке запроса через JS следующим образом:

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)
15 голосов
/ 03 января 2013

Спасибо!

Просто чтобы уточнить для более общего использования.

Вам нужен тег js с var AUTH_TOKEN в вашей голове. Должно быть что-то вроде этого.

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

А затем просто введите свой authenticity_token = AUTH_TOKEN в данные ajax, если вам не нужно использовать parent (форму) или что-то подобное.

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

Спасибо ребятам выше за то, что поделились этими знаниями!

3 голосов
/ 10 мая 2013

Я только что столкнулся с этой проблемой, но я попробовал этот подход в моем файле application.js:

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

Это оригинальный вопрос, в котором я получил идею: ajaxSend Question

3 голосов
/ 27 сентября 2011

Вы можете включить AUTH_TOKEN в саму форму в качестве скрытого ввода.

<input type="hidden" name="AUTH_TOKEN">1234abcd</input>
0 голосов
/ 13 апреля 2019

В Rails 5.1+ токен CSRF автоматически добавляется, если вы используете встроенный JS-помощник Rails для запросов AJAX (от rails-ujs), например:

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

Эта библиотека также предоставляет вам помощника для получения токена CSRF вручную, если он вам нужен:

Rails.csrfToken();
0 голосов
/ 09 июня 2017

Простое использование form_tag автоматически включает параметр токена CSRF. Rails поддерживает «Ненавязчивый Javascript», что означает, что форма будет по-прежнему отправляться через AJAX. Действия контроллера поддерживают блок «reply_to», и вы можете использовать расширение .js.erb для внесения изменений на веб-странице в ответ на отправку формы.

...