ActionController::Redirecting
Skip to Content
Skip to Search
Ruby on Rails 8.1.3
Module
ActionController::Redirecting
actionpack/lib/action_controller/metal/redirecting.rb
v8.1.3
Namespace
CLASS
ActionController::Redirecting::OpenRedirectError
CLASS
ActionController::Redirecting::PathRelativeRedirectError
CLASS
ActionController::Redirecting::UnsafeRedirectError
Methods
redirect_back
redirect_back_or_to
redirect_to
url_from
Included Modules
ActionController::UrlFor
Constants
ILLEGAL_HEADER_VALUE_REGEX
/[\x00-\x08\x0A-\x1F]/
Instance Public methods
redirect_back
(fallback_location:, allow_other_host: _allow_other_host, **args)
Link
Soft deprecated alias for
redirect_back_or_to
where the
fallback_location
location is supplied as a keyword argument instead of the first positional argument.
Source:
show
on GitHub
# File actionpack/lib/action_controller/metal/redirecting.rb, line 169
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, allow_other_host: _allow_other_host, **options)
Link
Redirects the browser to the page that issued the request (the referrer) if possible, otherwise redirects to the provided default fallback location.
The referrer information is pulled from the HTTP
Referer
(sic) header on the request. This is an optional header and its presence on the request is subject to browser security settings and user preferences. If the request is missing this header, the
fallback_location
will be used.
redirect_back_or_to
({
action:
"show"
id:
})
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
Options
:allow_other_host
- Allow or disallow redirection to the host that is different to the current host, defaults to true.
All other options that can be passed to
redirect_to
are accepted as options, and the behavior is identical.
Source:
show
on GitHub
# File actionpack/lib/action_controller/metal/redirecting.rb, line 196
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
redirect_to
(options = {}, response_options = {})
Link
Redirects the browser to the target specified in
options
. This parameter can be any one of:
Hash
- The URL will be generated by calling
url_for
with the
options
Record
- The URL will be generated by calling
url_for
with the
options
, which will reference a named URL for that record.
String
starting with
protocol://
(like
) or a protocol relative reference (like
//
) - Is passed straight through as the target for redirection.
String
not containing a protocol - The current protocol and host is prepended to the string.
Proc
- A block that will be executed in the controller’s context. Should return any option accepted by
redirect_to
Examples
redirect_to
action:
"show"
id:
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
) }
The redirection happens as a
302 Found
header unless otherwise specified using the
:status
option:
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
The status code can either be a standard
HTTP Status code
as an integer, or a symbol representing the downcased, underscored and symbolized description. Note that the status code must be a 3xx HTTP code, or redirection will not occur.
If you are using XHR requests other than GET or POST and redirecting after the request then some browsers will follow the redirect using the original request method. This may lead to undesirable behavior such as a double DELETE. To work around this you can return a
303 See Other
status code which will be followed using a GET request.
redirect_to
posts_url
status:
:see_other
redirect_to
action:
'index'
status:
303
It is also possible to assign a flash message as part of the redirection. There are two special accessors for the commonly used flash names
alert
and
notice
as well as a general purpose
flash
bucket.
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"
Statements after
redirect_to
in our controller get executed, so
redirect_to
doesn’t stop the execution of the function. To terminate the execution of the function immediately after the
redirect_to
, use return.
redirect_to
post_url
@post
and
return
Open Redirect protection
By default,
Rails
protects against redirecting to external hosts for your app’s safety, so called open redirects.
Here
redirect_to
automatically validates the potentially-unsafe URL:
redirect_to
params
:redirect_url
The
action_on_open_redirect
configuration option controls the behavior when an unsafe redirect is detected: *
:log
- Logs a warning but allows the redirect *
:notify
- Sends an Active Support notification for monitoring *
:raise
- Raises an
UnsafeRedirectError
To allow any external redirects pass
allow_other_host: true
, though using a user-provided param in that case is unsafe.
redirect_to
"https://rubyonrails.org"
allow_other_host:
true
See
url_from
for more information on what an internal and safe URL is, or how to fall back to an alternate redirect URL in the unsafe case.
Path Relative URL Redirect Protection
Rails
also protects against potentially unsafe path relative URL redirects that don’t start with a leading slash. These can create security vulnerabilities:
redirect_to
"example.com"
# Creates http://yourdomain.comexample.com
redirect_to
"@attacker.com"
# Creates http://yourdomain.com@attacker.com
# which browsers interpret as user@host
You can configure how
Rails
handles these cases using:
config
action_controller
action_on_path_relative_redirect
:log
# default
config
action_controller
action_on_path_relative_redirect
:notify
config
action_controller
action_on_path_relative_redirect
:raise
:log
- Logs a warning but allows the redirect
:notify
- Sends an Active Support notification but allows the redirect (includes stack trace to help identify the source)
:raise
- Raises an
UnsafeRedirectError
Source:
show
on GitHub
# File actionpack/lib/action_controller/metal/redirecting.rb, line 150
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
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
url_from
(location)
Link
Verifies the passed
location
is an internal URL that’s safe to redirect to and returns it, or nil if not. Useful to wrap a params provided redirect URL and fall back to an alternate URL to redirect to:
redirect_to
url_from
params
:redirect_url
])
||
root_url
The
location
is considered internal, and safe, if it’s on the same host as
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
Subdomains are considered part of the host:
# If request.host is on https://example.com or https://app.example.com, you'd get:
url_from
"https://dev.example.com/profile"
# => nil
NOTE: there’s a similarity with
url_for
, which generates an internal URL from various options from within the app, e.g.
url_for(@post)
. However,
url_from
is meant to take an external parameter to verify as in
url_from(params[:redirect_url])
Source:
show
on GitHub
# File actionpack/lib/action_controller/metal/redirecting.rb, line 254
def
url_from
location
location
location
presence
location
if
location
&&
_url_host_allowed?
location
end