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