Подтвердить что ты не робот

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?

4b9b3361

Ответ 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 или что-то.