Поймать ошибку 401 в Rails с Devise, когда у пользователя открыто несколько окон

Сценарий таков: у пользователя есть 2 окна, в которых он / она вошел в систему. Он / она выходит из одного, остается в системе в другом, а затем в последнем вызывает какое-то действие, скажем, отправку формы.

Первоначально произошло то, что он выдал недопустимую ошибку токена аутентификации. Я обновил protect_from_forgery в ApplicationController до with: :null_session, чтобы вместо Exception выдавалось 401.

Большой! Теперь для шага 2, вместо того, чтобы пользователь просто видел строку текста с надписью You need to sign in or sign up before continuing., я хотел бы перенаправить его/ее обратно на страницу входа.

Вот тут у меня проблемы... Я читал это руководство: http://agileleague.com/blog/rails-3-2-custom-error-pages-the-exceptions_app-и-тестирование-с-капибарой/ в котором говорится, что 401 ошибка по умолчанию не перехватывается рельсами. В руководстве есть две строки кода, которые будут его определять и перехватывать, а затем одна строка кода в маршруте, которая заставит маршрут работать. В основном это выглядит так:

# add to app/controllers/application_controller.rb
class UnauthorizedException < Exception; end

# add to app/config/application.rb
config.action_dispatch.rescue_responses.merge!('ApplicationController::UnauthorizedException' => :unauthorized)

# add to routes (in my case this is what I've done for Devise)
devise_scope :user do
  match '/401', to: 'users/sessions#new', type: "401", via: :get
end

Теперь я очень хорошо разбираюсь в обработке исключений, но мне это кажется неполным... и это тоже не работает. Если я перейду к /401 на своем локальном сервере, я попаду на страницу входа, так что маршрутизация работает. Но если я воспроизведу описанный выше сценарий, который в первую очередь приводит к ошибке 401, а не к перенаправлению, я все равно останусь на странице с одной строкой обычного текста.

Помощь?


person james    schedule 12.07.2015    source источник
comment
Если вы используете before_action :authenticate_user!, то Devise должен автоматически перенаправить на путь входа. Это произойдет до того, как rails попытается оценить токен CSRF, который должен быть недействительным, поскольку сеанс должен быть только что сброшен. Похоже, вы делаете что-то не так и зациклились на сеансе.   -  person max    schedule 12.07.2015
comment
хм.... Я использую before_action :authenticate_user!... где я мог ошибиться?   -  person james    schedule 12.07.2015
comment
Другими словами, как вы думаете, есть ли метод, с помощью которого я могу принудительно установить порядок фильтров «до»?   -  person james    schedule 12.07.2015
comment
stackoverflow.com/questions/18582400 /   -  person max    schedule 12.07.2015
comment
Спасибо @max. Интересно, есть ли у вас еще хорошие идеи для меня... Я прочитал кучу SO, а затем начал с попытки выяснить порядок моего текущего filter_chain. Используя этот код: makandracards.com/makandra/ о том, как проверить контроллер filter_chain, я определил, что порядок (для 2 пользовательских контроллеров) 1) verify_authenticity_token, 2) set_xhr_redirected_to, 3) set_request_method_cookie. Другими словами, нет authenticate_user!. Тем не менее, только в одном из контроллеров у меня есть эта проблема. Мысли?   -  person james    schedule 12.07.2015
comment
Попробуйте prepend_before_action :authenticate_user! попытаться поместить его в начало цепочки фильтров — вы хотите, чтобы Devise перенаправлял до того, как Rails попытается проверить токен CSRF.   -  person max    schedule 12.07.2015
comment
Извините, @max, что вы ответили до того, как я успел отредактировать свой комментарий: authenticate_user! присутствовал, я просто пропустил его в списке, а prepend успешно выдвинул его на передний план. Теперь, когда я просматриваю filter_chain в консоли, authenticate_user! действительно первый. Но на локальном сервере, когда я тестирую; это все еще в прошлом, и проблема сохраняется! Также следует отметить, что у меня есть 2 пользовательских контроллера; только в одном это проблема; в другом у меня нет prepend, в консоли authenticate_user! отображается последним, но работает нормально   -  person james    schedule 12.07.2015