ПРЕДУПРЕЖДЕНИЕ. Невозможно проверить рельсы аутентификации маркера CSRF.

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

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

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

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

Изменить: Мое решение

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

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

Ответ 1

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

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

  • Добавьте 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')
  }
});

Ответ 2

Лучший способ сделать это - просто использовать <%= form_authenticity_token.to_s %>, чтобы распечатать токен непосредственно в коде rails. Вам не нужно использовать javascript для поиска dom для токена 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) %>"
})

Ответ 3

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

<%= token_tag(nil) %>

Не забывайте параметр.

Ответ 4

Уклонение от более старого приложения до 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.

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

Ответ 5

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

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

<%= 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);
    }
});

Ответ 6

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

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

$.ajax({
  url: url,
  method: 'post',
  beforeSend: $.rails.CSRFProtection,
  data: {
    // ...
  }
})

Ответ 8

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

$.ajax({ 
  url: url,
  type: 'POST',
  beforeSend: function(xhr) {
    xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
  },
  xhrFields: {
    withCredentials: true
  }
});

Ответ 9

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

Нормальный 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'))}
    });
});

Кофе Script:

  $('#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'))
  }

Ответ 10

Если вы используете javascript с jQuery для генерации токена в вашей форме, это работает:

<input name="authenticity_token" 
       type="hidden" 
       value="<%= $('meta[name=csrf-token]').attr('content') %>" />

Очевидно, что вам нужно иметь <%= csrf_meta_tag %> в вашем макете Ruby.

Ответ 11

Используйте jquery.csrf(https://github.com/swordray/jquery.csrf).

  • Rails 5.1 или новее

    $ yarn add jquery.csrf
    
    //= require jquery.csrf
    
  • Rails 5.0 или до

    source 'https://rails-assets.org' do
      gem 'rails-assets-jquery.csrf'
    end
    
    //= require jquery.csrf
    
  • Исходный код

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

Ответ 12

Для тех из вас, кому нужен ответ jQuery, вы можете просто добавить следующее:

xmlhttp.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));

Здесь очень простой пример:

xmlhttp.open("POST","example.html",true);
xmlhttp.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
xmlhttp.send();

Ответ 13

nop

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

//= require jquery_ujs

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

Ответ 14

Если вы не используете jQuery и используете что-то вроде fetch API для запросов, вы можете использовать следующие, чтобы получить csrf-token:

document.querySelector('meta[name="csrf-token"]').getAttribute('content')

fetch('/users', {
  method: 'POST',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').getAttribute('content')},
    credentials: 'same-origin',
    body: JSON.stringify( { id: 1, name: 'some user' } )
    })
    .then(function(data) {
      console.log('request succeeded with JSON response', data)
    }).catch(function(error) {
      console.log('request failed', error)
    })

Ответ 16

Я использую Rails 4.2.4 и не могу понять, почему я получаю:

Can't verify CSRF token authenticity

У меня в макете:

<%= csrf_meta_tags %>

В контроллере:

protect_from_forgery with: :exception

Вызов tcpdump -A -s 999 -i lo port 3000 показывал установленный заголовок (несмотря на то, что не нужно устанавливать заголовки с ajaxSetup - это уже было сделано):

X-CSRF-Token: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
DNT: 1
Content-Length: 125
authenticity_token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

В конце концов это было неудачно, потому что я отключил cookies. CSRF не работает без включения файлов cookie, поэтому это еще одна возможная причина, если вы видите эту ошибку.