Ruby-on-Rails: как избавиться от страницы "вы перенаправлены"

Я отменяю ответный запрос Devise, чтобы установить код состояния 401. Однако, когда пользователь не может войти в систему, они перенаправляются на страницу с ссылкой "вы перенаправлены". Если я удалю этот :status => 401 из перенаправления, он отлично работает.

class CustomFailure < Devise::FailureApp
    def redirect_url
      new_user_session_url(:subdomain => 'secure')
    end

    def respond
        if http_auth?
           http_auth
        else
           store_location!
           flash[:alert] = i18n_message unless flash[:notice]
           redirect_to redirect_url, :status => 401
        end
    end
end

изменить

В качестве альтернативы я хотел бы отобразить флеш-сообщение и остаться на одной странице, но добавив эту строку кода:

render :text => "unauthorized", :status => 401

заставляет ruby ​​жаловаться:

undefined method `render' for #<CustomFailure:0x00000103367f28>

Что здесь происходит?

Ответы

Ответ 1

Соответствующие статусы HTTP для перенаправления в формате 30x (наиболее часто используются 301 и 302). По умолчанию помощник redirect_to устанавливает заголовок состояния 302 в ответе HTTP. Если вы переопределите это значение и установите его на 401, ваш веб-браузер предположит, что ответ является обычной веб-страницей и будет отображать тело ответа, которое в перенаправлении является текстом шаблона "Вы перенаправляетесь".

Ответ 2

Я действительно сталкивался с этой проблемой на нашем сервере QA, но не локально. Оказалось, что наша memcache перехватывала сообщение и отображала его как 200 и вызывала это сообщение. Это косвенно связано с нашими настройками memcache, которые не ожидали перенаправления из GET.

From: 
$document_root/cache/$uri.html /cache/$uri /cache/$uri.html $uri @memcached

To:
$document_root/cache/$uri.html /cache/$uri /cache/$uri.html $uri @rails

Ответ 3

Как сказано @pantulis, браузер отобразит это стандартное сообщение, если код ответа не является 3xx

Чтобы обойти это, вы можете выполнить перенаправление javascript:

# example with status 500:
render text: "<script>window.location = '#{url}';</script>", status: 500

Это вне курса действует только в том случае, если вы уверены, что все ваши пользователи используют javascript. Если ваше приложение может быть просмотрено пользователями, которые могут отключить javascript, вы также должны включить тег noscript и вернуться в стандартное сообщение "Вы перенаправлены"

Ответ 4

Когда у меня есть эта проблема, то, что я делал в прошлом, примерно такая:

#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  after_filter :check_page_content
  ...
  private
  def check_page_content
    if response.body.include? "You are being"
      html_doc = Nokogiri::HTML(response.body)
      uri = html_doc.css('a').map { |link| link['href'] }.first
      response.body = "<script>
                         window.location.replace('#{uri}');
                       </script>"
    end
  end
end

То, что я делаю, это проверить, является ли содержимое страницы "Вы являетесь". если это правда, я знаю, что я не там, где хочу. и я просто обновляю страницу до того места, где я действительно хочу быть с помощью Javascript. Я знаю, что это не самое элегантное решение, но оно действительно помогает

Счастливый взлом