Spec-Zone.ru › Ruby on Rails 8.0

модуль ActionController::Redirecting

Включенные модули:
ActionController::UrlFor

Константы

ILLEGAL_HEADER_VALUE_REGEX

Общедоступные методы экземпляров

redirect_back(fallback_location:, allow_other_host: _allow_other_host, **args) Показать исходный код
# File actionpack/lib/action_controller/metal/redirecting.rb, line 122
def redirect_back(fallback_location:, allow_other_host: _allow_other_host, **args)
  redirect_back_or_to fallback_location, allow_other_host: allow_other_host, **args
end

Мягко устаревшее псевдоним для redirect_back_or_to, где значение fallback_location местоположения предоставляется в качестве именованного аргумента вместо первого позиционного аргумента.

redirect_back_or_to(fallback_location, allow_other_host: _allow_other_host, **options) Показать исходный код
# File actionpack/lib/action_controller/metal/redirecting.rb, line 149
def redirect_back_or_to(fallback_location, allow_other_host: _allow_other_host, **options)
  if request.referer && (allow_other_host || _url_host_allowed?(request.referer))
    redirect_to request.referer, allow_other_host: allow_other_host, **options
  else
    # The method level `allow_other_host` doesn't apply in the fallback case, omit
    # and let the `redirect_to` handling take over.
    redirect_to fallback_location, **options
  end
end

Перенаправляет браузер на страницу, которая инициировала запрос (ссылка на referrer), если это возможно, в противном случае перенаправляет на предоставленное значение fallback_location.

Информация о ссылке на referrer извлекается из HTTP Referer (sic) заголовка запроса. Это необязательный заголовок, и его присутствие в запросе зависит от настроек безопасности браузера и предпочтений пользователя. Если в запросе отсутствует этот заголовок, будет использовано значение fallback_location.

redirect_back_or_to({ action: "show", id: 5 })
redirect_back_or_to @post
redirect_back_or_to "http://www.rubyonrails.org"
redirect_back_or_to "/images/screenshot.jpg"
redirect_back_or_to posts_url
redirect_back_or_to proc { edit_post_url(@post) }
redirect_back_or_to '/', allow_other_host: false

Параметры

  • :allow_other_host — Разрешить или запретить перенаправление на хост, отличный от текущего хоста; по умолчанию значение true.

Все остальные параметры, которые можно передать в redirect_to, принимаются в качестве параметров, и поведение идентично.

redirect_to(options = {}, response_options = {}) Показать исходный код
# File actionpack/lib/action_controller/metal/redirecting.rb, line 103
def redirect_to(options = {}, response_options = {})
  raise ActionControllerError.new("Cannot redirect to nil!") unless options
  raise AbstractController::DoubleRenderError if response_body

  allow_other_host = response_options.delete(:allow_other_host) { _allow_other_host }

  proposed_status = _extract_redirect_to_status(options, response_options)

  redirect_to_location = _compute_redirect_to_location(request, options)
  _ensure_url_is_http_header_safe(redirect_to_location)

  self.location      = _enforce_open_redirect_protection(redirect_to_location, allow_other_host: allow_other_host)
  self.response_body = ""
  self.status        = proposed_status
end

Перенаправляет браузер на целевой ресурс, указанный в options. Этот параметр может быть любым из следующих:

  • Hash — URL будет сгенерирован вызовом url_for с options.

  • Record — URL будет сгенерирован вызовом url_for с options, что будет ссылаться на именованный URL для данного объекта.

  • String, начинающийся с protocol:// (например, http:// или относительная ссылка к протоколу (например, //) — Передаётся напрямую как целевой ресурс для перенаправления.

  • String без указания протокола — К строке добавляется текущий протокол и хост.

  • Proc — Блок, который будет выполнен в контексте контроллера. Должен вернуть любой параметр, принятый redirect_to.

Примеры

redirect_to action: "show", id: 5
redirect_to @post
redirect_to "http://www.rubyonrails.org"
redirect_to "/images/screenshot.jpg"
redirect_to posts_url
redirect_to proc { edit_post_url(@post) }

Перенаправление происходит в виде заголовка 302 Found заголовка, если не указано иное с помощью параметра :status:

redirect_to post_url(@post), status: :found
redirect_to action: 'atom', status: :moved_permanently
redirect_to post_url(@post), status: 301
redirect_to action: 'atom', status: 302

Код состояния может быть стандартным кодом состояния HTTP HTTP Status code в виде целого числа или символом, представляющим описание в нижнем регистре, с подчёркиванием и символом. Обратите внимание, что код состояния должен быть кодом HTTP 3xx, иначе перенаправление не произойдёт.

Если вы используете запросы XHR, отличные от GET или POST, и перенаправляете после запроса, некоторые браузеры будут следовать перенаправлению с использованием исходного метода запроса. Это может привести к нежелательному поведению, такому как двойное выполнение DELETE. Чтобы обойти эту проблему, вы можете вернуть код состояния 303 See Other, который будет выполнен с помощью запроса GET.

redirect_to posts_url, status: :see_other
redirect_to action: 'index', status: 303

Также можно назначить сообщение всплывающей подсказки в рамках перенаправления. Существуют два специальных доступа для часто используемых имён всплывающей подсказки alert и notice, а также общий параметр flash.

redirect_to post_url(@post), alert: "Watch it, mister!"
redirect_to post_url(@post), status: :found, notice: "Pay attention to the road"
redirect_to post_url(@post), status: 301, flash: { updated_post_id: @post.id }
redirect_to({ action: 'atom' }, alert: "Something serious happened")

Выражения после redirect_to в нашем контроллере выполняются, поэтому redirect_to не останавливает выполнение функции. Чтобы немедленно завершить выполнение функции после redirect_to, используйте return.

redirect_to post_url(@post) and return

Защита от открытых перенаправлений

По умолчанию, Rails защищает от перенаправлений на внешние хосты для безопасности вашего приложения, так называемые открытые перенаправления. Примечание: это было новым значением по умолчанию в Rails 7.0, после обновления необходимо включить эту функцию, раскомментировав строку с raise_on_open_redirects в config/initializers/new_framework_defaults_7_0.rb

Здесь redirect_to автоматически проверяет потенциально небезопасный URL:

redirect_to params[:redirect_url]

Выбрасывает UnsafeRedirectError в случае небезопасного перенаправления.

Чтобы разрешить любые внешние перенаправления, передайте allow_other_host: true, хотя использование пользовательского параметра в этом случае небезопасно.

redirect_to "https://rubyonrails.org", allow_other_host: true

См. url_from для получения дополнительной информации о том, что такое внутренний и безопасный URL-адрес или о том, как перейти к альтернативному URL-адресу перенаправления в случае небезопасности.

url_from(location) Показать исходный код
# File actionpack/lib/action_controller/metal/redirecting.rb, line 203
def url_from(location)
  location = location.presence
  location if location && _url_host_allowed?(location)
end

Проверяет, является ли переданный location внутренним URL, безопасным для перенаправления, и возвращает его или nil, если нет. Полезно для обертывания URL-адреса, предоставленного параметрами, и перехода к альтернативному URL-адресу перенаправления:

redirect_to url_from(params[:redirect_url]) || root_url

location считается внутренним и безопасным, если он находится на том же хосте, что и request.host:

# If request.host is example.com:
url_from("https://example.com/profile") # => "https://example.com/profile"
url_from("http://example.com/profile")  # => "http://example.com/profile"
url_from("http://evil.com/profile")     # => nil

Поддомены считаются частью хоста:

# If request.host is on https://example.com or https://app.example.com, you'd get:
url_from("https://dev.example.com/profile") # => nil

ПРИМЕЧАНИЕ: есть сходство с url_for, который генерирует внутренний URL-адрес из различных параметров приложения, например, url_for(@post). Однако url_from предназначен для получения внешнего параметра для проверки, как в url_from(params[:redirect_url]).

© 2004–2021 David Heinemeier Hansson
Licensed under the MIT License.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API