Rails 3.1 - CSRF игнорируется?

вот моя проблема,

У меня есть приложение rails 3.1, и я пытаюсь выполнить запрос ajax, но получаю предупреждающее сообщение ". ПРЕДУПРЕЖДЕНИЕ: не удается проверить подлинность CSRF-токена"...

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

$.ajaxSetup({
  beforeSend: function(xhr) {
    xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
  }
});

My Gemfile содержит gem jquery-rails ( >= 1.0.12), и мне нужно jquery и jquery-ujs в верхней части моего приложения .js.

Даже при этом сообщение все еще появляется. Я что-то забыл?

Спасибо за помощь.

Ответ 1

Что работало для меня - при работе без форм - это включить результат <%= form_authenticity_token %> в полезную нагрузку данных ajax. Поэтому я делаю что-то вроде того, что было предложено tehprofessor в html:

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

затем в javascript:

tokentag = $('#tokentag').val()
submitdata = { "authenticity_token": tokentag, ...+whatever else you need to include+...}

затем вызовите $.ajax с помощью submitdata.

Ответ 2

У меня была такая же проблема. Я пытался поймать javascript событие (you_tube игрока завершено) и Ajax обратно на мой сервер, чтобы сообщить мне. Я получал:

WARNING: Can't verify CSRF token authenticity

всякий раз, когда jQuery ajax-вызов ударил моего сервера. Я добавил исправление кода выше

$.ajaxSetup({
    beforeSend: function(xhr) {
        xhr.setRequestHeader('X-CSRF-Token',
                             $('meta[name="csrf-token"]').attr('content'));
    }
});

и он отлично работает. Я думаю, что только разница в моем макете у меня есть

<%= csrf_meta_tags %>

а не csrf_method_tag, как вы упомянули в своем оригинальном посте.
Так что спасибо за исправление, это было в исходном сообщении.

Ответ 3

Вероятно, вам этого и не нужно в коде. Камни jquery-rails автоматически устанавливают токен CSRF по всем запросам Ajax по умолчанию.

Ответ 4

Просто сделайте это прямо на своем вызове AJAX, и он будет работать правильно!

  $.ajax({
            type: //method,
            beforeSend: function(xhr){
                xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))
            },
            url: //parameter,
            dataType: 'html',
            success: function(data, textStatus, jqXHR) {
               // some code
            }
  });

Ответ 5

Пробовали ли вы использовать скрытый элемент формы с токеном аутентификации?

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

У меня была такая же ошибка, и это разрешило ее. Это потому, что я не использовал встроенные помощники формы...

Ответ 6

Одна из причин может заключаться в том, что вы вызываете вызов AJAX до загрузки документа, поэтому JQuery не может получить токен CSRF.

Ответ 7

Проблема заключается в том, что вам нужно извлечь новый токен после запроса AJAX POST, поскольку после использования токена он становится недействительным. Вот код для этого:

В rails всякий раз, когда отправляется ответ POST, добавьте эти параметры в ответ:

def someMethod:
    result[:csrfParam] = request_forgery_protection_token
    result[:csrfToken] = form_authenticity_token
    render :json => result
end

Теперь на стороне JS в функции успеха каждого метода POST вы можете вызвать эту функцию:

var setCsrfToken = function(param, token) {
    if(param == null || token == null) {
        console.error("New CSRF param/token not present");
    }
    $("input[name='" + param + "']").val(token);
}

вот так:

setCsrfToken(result["csrfParam"], result["csrfToken"]);

Эта функция будет reset все параметры authenticity_token во всех формах POST, чтобы следующий запрос имел действительный токен. Вы должны убедиться, что это происходит в каждом вызове POST, иначе вы продолжите сталкиваться с этой проблемой.

Кроме того, CSRF не предназначен для предотвращения щелчка, это отдельная атака вообще, где другой веб-сайт может заставить пользователя щелкнуть ссылку, которая выполняет действие на вашем веб-сайте с сеансом пользователя.