Разработать выход из системы на post по другому маршруту

#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%>