ВНИМАНИЕ: Невозможно проверить рельсы подлинности токена CSRF. - PullRequest
230 голосов
/ 26 августа 2011

Я отправляю данные из представления на контроллер с AJAX, и я получил эту ошибку:

ПРЕДУПРЕЖДЕНИЕ: не удается проверить подлинность токена CSRF

Я думаю, что долженотправьте этот токен с данными.

Кто-нибудь знает, как я могу это сделать?

Редактировать: Мое решение

Я сделал это, поставив следующеекод внутри поста AJAX:

headers: {
  'X-Transaction': 'POST Example',
  'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},

Ответы [ 17 ]

362 голосов
/ 18 ноября 2011

Вы должны сделать это:

  1. Убедитесь, что в вашем макете <%= csrf_meta_tag %>

  2. Добавьте beforeSend ко всем запросам ajax для установки заголовка, как показано ниже:


$.ajax({ url: 'YOUR URL HERE',
  type: 'POST',
  beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))},
  data: 'someData=' + someData,
  success: function(response) {
    $('#someDiv').html(response);
  }
});

Для отправки токена во всех запросах вы можете использовать:

$.ajaxSetup({
  headers: {
    'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
  }
});
31 голосов
/ 25 ноября 2011

Лучший способ сделать это - просто использовать <%= form_authenticity_token.to_s %> для распечатки токена непосредственно в коде rails.Вам не нужно использовать javascript для поиска в домене токена csrf, как упоминалось в других сообщенияхпросто добавьте опцию заголовков, как показано ниже;

$.ajax({
  type: 'post',
  data: $(this).sortable('serialize'),
  headers: {
    'X-CSRF-Token': '<%= form_authenticity_token.to_s %>'
  },
  complete: function(request){},
  url: "<%= sort_widget_images_path(@widget) %>"
})
22 голосов
/ 26 августа 2011

Если я правильно помню, вам нужно добавить следующий код в форму, чтобы избавиться от этой проблемы:

<%= token_tag(nil) %>

Не забудьте параметр.

15 голосов
/ 06 мая 2013

Действительно самый простой способ. Не беспокойтесь о смене заголовков.

Убедитесь, что у вас есть:

<%= csrf_meta_tag %> in your layouts/application.html.erb

Просто сделайте скрытое поле ввода примерно так:

<input name="authenticity_token" 
               type="hidden" 
               value="<%= form_authenticity_token %>"/>

Или, если вы хотите jQuery Ajax сообщение:

$.ajax({     
    type: 'POST',
    url: "<%= someregistration_path %>",
    data: { "firstname": "text_data_1", "last_name": "text_data2", "authenticity_token": "<%= form_authenticity_token %>" },                                                                                  
    error: function( xhr ){ 
      alert("ERROR ON SUBMIT");
    },
    success: function( data ){ 
      //data response can contain what we want here...
      console.log("SUCCESS, data="+data);
    }
});
13 голосов
/ 10 января 2012

Обновление старого приложения до rails 3.1, включая метатег csrf, до сих пор не решило проблему.В блоге rubyonrails.org они дают несколько советов по обновлению, а именно эту строку jquery, которая должна идти в разделе заголовка вашего макета:

$(document).ajaxSend(function(e, xhr, options) {
 var token = $("meta[name='csrf-token']").attr("content");
  xhr.setRequestHeader("X-CSRF-Token", token);
});

взято из этого сообщения в блоге: http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails.

В моем случае сеанс сбрасывался при каждом запросе ajax.Добавление кода выше решило эту проблему.

10 голосов
/ 08 июля 2015
  1. Убедитесь, что в вашем макете <%= csrf_meta_tag %>
  2. Добавьте beforeSend для включения токена csrf в запрос ajax для установки заголовка.Это требуется только для post запросов.

Код для чтения токена csrf доступен в rails/jquery-ujs, поэтому imho проще всего использовать его следующим образом:*

$.ajax({
  url: url,
  method: 'post',
  beforeSend: $.rails.CSRFProtection,
  data: {
    // ...
  }
})
6 голосов
/ 23 ноября 2014

Самые популярные ответы здесь верны, но не будут работать, если вы выполняете междоменных запросов, потому что сеанс будет недоступен, если вы явно не скажете jQuery пропустить cookie сеанса.Вот как это сделать:

$.ajax({ 
  url: url,
  type: 'POST',
  beforeSend: function(xhr) {
    xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
  },
  xhrFields: {
    withCredentials: true
  }
});
6 голосов
/ 18 ноября 2011

Я просто решил связать это здесь, так как статья содержит большую часть ответа, который вы ищете, и это также очень интересно

http://www.kalzumeus.com/2011/11/17/i-saw-an-extremely-subtle-bug-today-and-i-just-have-to-tell-someone/

5 голосов
/ 08 апреля 2014

Вы можете написать это глобально, как показано ниже.

Обычный JS:

$(function(){

    $('#loader').hide()
    $(document).ajaxStart(function() {
        $('#loader').show();
    })
    $(document).ajaxError(function() {
        alert("Something went wrong...")
        $('#loader').hide();
    })
    $(document).ajaxStop(function() {
        $('#loader').hide();
    });
    $.ajaxSetup({
        beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))}
    });
});

Сценарий кофе:

  $('#loader').hide()
  $(document).ajaxStart ->
    $('#loader').show()

  $(document).ajaxError ->
    alert("Something went wrong...")
    $('#loader').hide()

  $(document).ajaxStop ->
    $('#loader').hide()

  $.ajaxSetup {
    beforeSend: (xhr) ->
      xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
  }
4 голосов
/ 25 декабря 2013

упс ..

Я пропустил следующую строку в моем приложении. Js

//= require jquery_ujs

Я заменил его и он работает ..

======= ОБНОВЛЕНО =========

Через 5 лет я вернулся с той же ошибкой, теперь у меня есть совершенно новый Rails 5.1.6 , и я снова нашел этот пост. Так же, как круг жизни.

Теперь, в чем заключалась проблема: Rails 5.1 удалена поддержка jquery и jquery_ujs по умолчанию и добавлено

//= require rails-ujs in application.js

Он делает следующие вещи:

  1. принудительное диалоговое окно подтверждения для различных действий;
  2. делать не-GET запросы от гиперссылок;
  3. заставляет формы или гиперссылки отправлять данные асинхронно с Ajax;
  4. при отправке формы кнопки отправки автоматически отключаются, чтобы избежать двойного щелчка. (от: https://github.com/rails/rails-ujs/tree/master)

Но почему он не включает токен csrf для запроса ajax? Если кто-то знает об этом подробно, просто прокомментируйте меня. Я ценю это.

В любом случае я добавил следующее в свой файл js, чтобы он работал (спасибо за другие ответы, которые помогли мне добраться до этого кода):

$( document ).ready(function() {
  $.ajaxSetup({
    headers: {
      'X-CSRF-Token': Rails.csrfToken()
    }
  });
  ----
  ----
});
...