【问题标题】:Opposite of Force_SSL in Rails?Rails 中 Force_SSL 的对面?
【发布时间】:2012-05-15 19:12:38
【问题描述】:

我正在运行一个 Rails 3.1.4 应用程序,它需要一些页面使用 force_ssl,但其他一些我不想使用 SSL。 force_ssl 有没有相反的东西,比如 force_http?问题是我有一些不需要 SSL 的页面,并且它们包含我无法使用 https 拉过来的元素(因此用户从浏览器收到不安全错误)。

发生的情况是,当有人转到 force_ssl 页面时它工作正常,但是当他们转到不是 force_ssl 的其他页面时,他们会从浏览器收到不安全的页面错误,因为 https 仍然存在。因此,我想强制我无法使元素 https 避免使用 SSL 的页面(即强制它回到 http)。

提前谢谢你。

【问题讨论】:

    标签: ruby-on-rails-3 ssl


    【解决方案1】:

    好的,我找到了一种似乎对我有用的方法:

    在我的会话控制器中我添加了这个:

    force_ssl :only => [:new, :create]
    

    所以只有这 2 个动作会通过 SSL 被调用。现在,用户成功登录后,页面将重定向到非 SSL 连接。

    至于强制页面为非 SSL,试试这个问题:Rails 3.1 Force Regular HTTP,使用 before_filter 查找 Joost 的答案。

    这是他发布的内容:

    class ApplicationController < ActionController::Base
      before_filter do
        if request.ssl && Rails.env.production?
          redirect_to :protocol => 'http://', :status => :moved_permanently
        end
      end
    end
    

    免责声明:上面的代码不是我的,我是从链接中的问题中复制过来的,只是为了方便放在这里。请访问上面的链接以查看其原始上下文。

    另外,关于强制使用非 SSL,我不确定这是个好主意。如果用户请求 SSL 连接并且您拥有证书,为什么不给他们呢?我同意 SSL 确实给浏览器带来了更大的压力,但有些人一直喜欢在 SSL 上冲浪。如果您的某些代码无法通过 SSL 运行,那么这是强制使用非 SSL 的正当理由。

    干杯。

    【讨论】:

    • 我尝试使用它,但它迫使我更改 request.ssl 以添加问号(正如有人在另一页上评论答案)。当我转到我的 force_ssl 页面时,我收到一条错误消息,提示重定向太多
    • 重定向过多意味着它陷入了循环。如果您将 before_filter 排除在外,会发生什么?即使您没有请求,是否所有页面都通过 SSL 提供?
    • 不,默认情况下不是。发生的情况是有人转到 https (force_ssl) 页面,并且通过链接访问的所有后续页面都采用 https。我认为您只是让这些页面在 https 中呈现而不是强制 http 是正确的
    • 你用的是什么浏览器?只是出于好奇。这可能是缓存情况。如果是 Safari,请在命令行上尝试:dscacheutil -flushcache。也可以试试 Chrome 看看你会得到什么。
    • 这听起来并不傻,但也许你可以发布另一个答案,说我应该让它成为 ssl 或其他东西,因为代码不起作用,我不想误导任何人(导致跨不同浏览器的无限循环重定向)。所以实际上我决定放手
    【解决方案2】:

    让它在没有循环的情况下工作。除非它发生在我不知道的浏览器中。

    before_filter do
      unless params[:controller] == 'whatever_controller_name_you_are_serving_https_to'
        if request.ssl? && Rails.env.production?
          redirect_to :protocol => 'http://', :status => :moved_permanently
        end
      end
    end
    

    【讨论】:

      【解决方案3】:

      假设(希望)您已升级到受支持的 Rails 版本,这是实现默认非 SSL 的一种简单方法,除非声明了 force_ssl。它的形式是ActiveSupport::Concern

      module ForceNoSSL
        extend ActiveSupport::Concern
      
        ACTION_OPTIONS = [:only, :except, :if, :unless]
      
        def force_no_ssl_redirect
          if request.ssl?
            options = {
              :protocol => 'http://',
              :host     => request.host,
              :path     => request.fullpath,
              :status   => :moved_permanently
            }
      
            redirect_to ActionDispatch::Http::URL.url_for(options)
          end
        end
      
        class_methods do
          def force_ssl(options = {})
            super
      
            action_options = options.slice(*ACTION_OPTIONS)
            skip_before_action :force_no_ssl_redirect, **action_options
          end
      
          def force_no_ssl
            before_action :force_no_ssl_redirect
          end
        end
      end
      

      然后在你的ApplicationController你:

      include ForceNoSSL
      force_no_ssl
      

      它的工作原理是默认情况下所有操作都将运行force_no_ssl_redirect 回调。如果已经是非ssl连接则什么都不做,否则请求会被重定向到http://

      但是,如果您已声明 force_ssl,则将跳过 force_no_ssl_redirect 回调(仅适用于 ACTION_OPTIONS 指定的那些操作)。

      您可以扩展它以允许 force_no_ssl 接受 URL 选项等...就像 force_ssl 操作一样,但对于我的用例来说,这不是必需的。

      附:很多代码来自ActionController::ForceSSL,因此请查看以获取更多信息。

      【讨论】:

        猜你喜欢
        • 2023-03-16
        • 2013-03-18
        • 1970-01-01
        • 1970-01-01
        • 2013-05-27
        • 1970-01-01
        • 2017-10-27
        • 1970-01-01
        相关资源
        最近更新 更多