#ruby-on-rails #devise
#ruby-на-рельсах #придумать #ruby-on-rails #разработка
Вопрос:
У меня действительно странная проблема с Devise. У меня настроен маршрут, который принимает как запросы get, так и post. При получении он показывает форму, при отправке — отправляет ее.
Когда я отправляю post XHR на маршрут, когда он попадает туда, он сообщает мне, что я не авторизован, и отправляет мне 401 несанкционированный. После этого я должен войти в систему, а затем я могу попробовать еще раз.
Я пытался разобраться в этом в течение нескольких часов, все, что я смог выяснить, это то, что мой метод контроллера не вызывается. Я ввел свой собственный фильтр авторизации перед фильтром, и он только что подтвердил, что к моменту вызова моего приложения rails пользователь больше не входит в систему.
Кроме того, если я открою форму, но не отправлю ее, я могу продолжить в обычном режиме. Где-то в этом XHR это заставляет devise выйти из системы.
Если у вас есть какие-либо идеи, пожалуйста, помогите, я понятия не имею, что происходит прямо сейчас…
Спасибо
-Скотт
РЕДАКТИРОВАТЬ: Добавление соответствующих фрагментов кода
routes.rb
match 'projects/:p/filebox' => 'projects#show', :via => ["get","post"], :as => 'project_filebox'
проект_контроллер.rb
before_filter :authenticate_user! # <--- By the time this gets called, the user is logged out
def show
# ^^^^ Doesnt get called. Logger shows that it recognized route though
logger.debug "-----------projects#show"
logger.debug "Current user logged in:" user_signed_in?.to_s
форма, которая отправляется
<form class="upload" action="<%= project_filebox_path(@project) %>?n=7amp;cType=<%= cType %>amp;fid=<%= fid %>" method="post" enctype="multipart/form-data">
<input type="file" name="file" multiple/>
<button>Upload</button>
<div>Add / Drag Files To Upload</div>
</form>
Javascript, который загружает XHR
formDataUpload = function (files, xhr, settings) {
var formData = new FormData(),
i;
$.each(getFormData(settings), function (index, field) {
formData.append(field.name, field.value);
});
for (i = 0; i < files.length; i = 1) {
formData.append(settings.fieldName, files[i]);
}
xhr.send(formData);
}
Если я пропустил какой-то важный фрагмент кода, дайте мне знать
Комментарии:
1. Это может помочь, если вы включите соответствующие части вашего кода, маршруты и т.д.
2. возможно, вызываются некоторые фильтры before, которые воспроизводят cookie приложения или делают что-то еще. Вы можете это проверить?
3. Только что попробовав это, я изменил свой ‘before_filter:authenticate_user!’ просто на метод с именем auth. В методе auth я просто распечатываю, вошел ли пользователь в систему в данный момент. Когда я загружаю страницу, пользователь входит в систему. Когда я отправляю XHR, auth показывает, что я вышел из системы.
Ответ №1:
Здесь не так уж много всего, кроме JS, но есть действительно сильное изменение, из-за которого у вас возникла проблема, потому что токен CSRF не устанавливается как часть вашего запроса. Это изменилось в различных версиях Rails 3.0.x, поэтому без кода трудно сказать наверняка.
Одним из самых простых тестов было бы отключить CSRF (например, удалить protect_from_forgery из ApplicationController). Если это сработает, у вас есть ответ, и вам нужно убедиться, что токен будет передан другим пользователям, или вы иным образом обработаете защиту от подделки.
Комментарии:
1. Спасибо за ответ! Я попытался закомментировать csrf_meta_tag в макете моего приложения, но, к сожалению, это не решило проблему. Похоже, вы на правильном пути. Есть ли какие-либо другие фрагменты кода, которые я мог бы предоставить, которые могли бы помочь?
2. Я просто хочу сказать, что ты был прав. Я был идиотом и не проверил проблему, которую вы правильно описали. Как только я это сделал, это начало работать. Большое вам спасибо за вашу помощь!
3. У меня была та же проблема, когда сеанс сбрасывался при отправке post, и пользователь выходил из системы при отправке формы. Комментарий protect_from_forgery исправил поведение, но теперь у меня не будет CSRF. @ScottRice и Джон Пол Ашенфелтер , как вы в итоге с этим справились ? Есть какие — нибудь примеры кода ? Я использую Rails 3.2.14
4. Конкретно для меня моя форма создавалась неправильно, потому что я делал это вручную. Я исправил проблему, заменив тег <form> на
form_for
вызов. Это автоматически добавило требуемые поля и решило проблему.
Ответ №2:
Я столкнулся с той же проблемой, когда у меня есть две формы на одной странице, одна из них отправляется на маршрут внутри приложения, другая отправляется на внешний адрес. Джон Пол Ашенфелтер прав, что это не имеет ничего общего с JS.
Как и вы, я не хочу отключать CSRF для всего сайта. В итоге я отключил защиту от подделки для метода, который отправляет на адрес вне сайта в контроллере:
protect_from_forgery :except => [:some_method]
И в форме, которая создает эту проблему CSRF:
<%= form_for :some_model, authenticity_token: false do%>