Ruby-on-rails Rails 3 SSL 路由从 https 重定向到 http
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3993651/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rails 3 SSL routing redirects from https to http
提问by Daniel
This question relates to this SO question and answer (rails-3-ssl-deprecation )where its suggested to handle ssl in rails 3 using routes.rb and routes like:
此问题与此SO 问答(rails-3-ssl-deprecation )有关,其中建议使用 routes.rb 和以下路线处理 rails 3 中的 ssl:
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 }
My problem is that links use relative paths(i think thats the correct term) and once I'm on a https page all the other links to other pages on the site then use https.
我的问题是链接使用相对路径(我认为这是正确的术语),一旦我在 https 页面上,所有其他链接到站点上的其他页面然后使用 https。
1) Whats the best way to get back to http for pages where https isn't required? Do I have to setup redirects for all them(I hope note) or is there a better way. Would the redirects be like this:
1) 对于不需要 https 的页面,返回 http 的最佳方法是什么?我是否必须为所有这些设置重定向(我希望注意)或者有更好的方法。重定向会是这样的:
match "foos(/*path)", :to => redirect { |_, request| "http://" + request.host_with_port + request.fullpath }
2) If redirects back to http are required, how do I handle a case where I want all methods to be http except one? ie foos(/*path) would be for all foos methods. But say I wanted foos/upload_foos to use ssl. I know how to require it
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
but if I put in the http redirect to the foos path what happens to https upload_foos?
但是如果我将 http 重定向放入 foos 路径,https upload_foos 会发生什么?
回答by Samuel
If you want all your links to be able to switch between http and https, you have to stop using the _pathhelper and switch to _urlhelpers.
如果您希望所有链接都能够在 http 和 https 之间切换,则必须停止使用_path帮助程序并切换到_url帮助程序。
After that, using a scope with the protocol parameter forced and protocol constraint makes the urls automatically switch.
之后,使用具有协议参数强制和协议约束的作用域使 url 自动切换。
routes.rb路由文件scope :protocol => 'https://', :constraints => { :protocol => 'https://' } do
resources :sessions
end
resources :gizmos
And now in your views:
现在在你看来:
<%= sessions_url # => https://..../sessions %>
<%= gizmos_url # => http://..../gizmos %>
Edit
编辑
This doesn't fix urls that go back to http when you are in https. To fix that you need to override url_for.
当您在 https 中时,这不会修复返回 http 的 url。要解决该问题,您需要覆盖url_for.
module ApplicationHelper
def url_for(options = nil)
if Hash === options
options[:protocol] ||= 'http'
end
super(options)
end
end
This will set the protocol to 'http' unless it was explicitly set (in routes or when calling the helper).
这会将协议设置为“http”,除非它被明确设置(在路由中或调用助手时)。
回答by Matt
This was a long time ago and I'm sure it can be improved, but back on some old version of rails I had this code in application controller. Not sure this is still valid for Rails 3, but it may be of some help:
这是很久以前的事情了,我相信它可以改进,但是回到一些旧版本的 rails 我在应用程序控制器中有这段代码。不确定这对 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
The USE_EXPLICIT_HOST_IN_ALL_LINKSwas some global configuration option, but you can ignore this.
这USE_EXPLICIT_HOST_IN_ALL_LINKS是一些全局配置选项,但您可以忽略它。
In each controller that required https, I'd add before_filter :require_ssland add that controller name and its methods to SECURE_ACTIONS. This probably can be improved by passing the action names to the before filter, or something.
在每个需要 https 的控制器中,我都会before_filter :require_ssl将该控制器名称及其方法添加到SECURE_ACTIONS. 这可能可以通过将动作名称传递给 before 过滤器或其他东西来改进。

