Rails 3 Переадресация маршрутизации SSL с https на http
Этот вопрос относится к этому вопросу SO (ответ на rails-3-ssl-deprecation)
), где предлагается использовать ssl в rails 3, используя route.rb и маршруты, например:
resources :sessions, :constraints => { :protocol => "https" }
# Redirect /foos and anything starting with /foos/ to https.
match "foos(/*path)", :to => redirect { |_, request| "https://" + request.host_with_port + request.fullpath }
Моя проблема заключается в том, что ссылки используют относительные пути (я думаю, что это правильный термин), и как только я нахожу на странице https все другие ссылки на другие страницы на сайте, используйте https.
1) Каков наилучший способ вернуться к http для страниц, где https не требуется? Должен ли я настраивать перенаправления для всех них (надеюсь, заметьте), или есть лучший способ. Будут ли переадресации такими:
match "foos(/*path)", :to => redirect { |_, request| "http://" + request.host_with_port + request.fullpath }
2) Если требуется перенаправить обратно на http, как мне обрабатывать случай, когда я хочу, чтобы все методы были http за исключением одного? т.е. foos (/* path) будет для всех foos-методов. Но скажу, что я хотел использовать foos/upload_foos для использования ssl. Я знаю, как его нужно
scope :constraints => { :protocol => "https" } do
match 'upload_foos' => 'foos#upload_foos', :via => :post, :as => :upload_foos
end
но если я поставлю http-перенаправление на путь foos, что произойдет с https upload_foos?
Ответы
Ответ 1
Если вы хотите, чтобы все ваши ссылки могли переключаться между http и https, вам нужно прекратить использование помощника _path
и переключиться на помощники _url
.
После этого использование области с параметром протокола принудительного и ограничения протокола делает автоматическое переключение URL.
<Б > routes.rb
scope :protocol => 'https://', :constraints => { :protocol => 'https://' } do
resources :sessions
end
resources :gizmos
И теперь в ваших взглядах:
<%= sessions_url # => https://..../sessions %>
<%= gizmos_url # => http://..../gizmos %>
Изменить
Это не исправляет URL-адреса, которые возвращаются к http, когда вы находитесь в https. Чтобы исправить это, вам необходимо переопределить url_for
.
В любом помощнике
module ApplicationHelper
def url_for(options = nil)
if Hash === options
options[:protocol] ||= 'http'
end
super(options)
end
end
Это установит протокол на "http", если он не был явно установлен (в маршрутах или при вызове помощника).
Ответ 2
Это было давно, и я уверен, что его можно улучшить, но вернувшись к какой-то старой версии рельсов, у меня был этот код в контроллере приложения. Не уверен, что это все еще актуально для Rails 3, но это может помочь:
private
SECURE_ACTIONS = {
:login => ["login", "login_customer", "remind_password", "add_customer", "add_or_login_customer"],
:store => ["checkout", "save_order"],
:order => ["show"] }
# Called as a before_filter in controllers that have some https:// actions
def require_ssl
unless ENV['RAILS_ENV'] != 'production' or @request.ssl?
redirect_to :protocol => 'https://', :action => action_name
# we don't want to continue with the action, so return false from the filter
return false
end
end
def default_url_options(options)
defaults = {}
if USE_EXPLICIT_HOST_IN_ALL_LINKS
# This will OVERRIDE only_path => true, not just set the default.
options[:only_path] = false
# Now set the default protocol appropriately:
if actions = SECURE_ACTIONS[ (options[:controller] || controller_name).to_sym ] and
actions.include? options[:action]
defaults[:protocol] = 'https://'
defaults[:host] = SECURE_SERVER if defined? SECURE_SERVER
else
defaults[:protocol] = 'http://'
defaults[:host] = NON_SECURE_SERVER if defined? NON_SECURE_SERVER
end
end
return defaults
end
USE_EXPLICIT_HOST_IN_ALL_LINKS
был частью глобальной конфигурации, но вы можете игнорировать это.
В каждом контроллере, который требует https, я бы добавил before_filter :require_ssl
и добавил это имя контроллера и его методы в SECURE_ACTIONS
. Вероятно, это можно улучшить, передав имена действий в фильтр before или что-то.