【问题标题】:Multiple redirects in rails when redirecting to HTTPS重定向到 HTTPS 时,rails 中的多个重定向
【发布时间】:2011-09-13 18:36:45
【问题描述】:

情况如下(我使用的是Rails 3.1)。

我有以下路线:

match 'login', :to => 'sessions#new'

相当标准。我的 Apache 虚拟主机文件中也有这个重定向规则:

RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule (/login$) https://%{HTTP_HOST}%{REQUEST_URI}

当我导航到 https://hostname.dom/login 时,我从浏览器中收到 301 状态代码(重定向太多)。有人可以指出这里的引擎盖后面发生了什么吗?谢谢。

【问题讨论】:

    标签: ruby-on-rails apache redirect https routes


    【解决方案1】:

    我会通过 rails 而不是 apache 来处理这个重定向。减少错误的机会并消除您的 Rails 应用程序与特定 Web 服务器(在本例中为 apache)的耦合。
    对于 Rails 3.0.X 和以前的使用 SSL_Requirement 和 3.1.X 及更高版本使用它在 'force_ssl' 方法中烘焙。

    ssl_requirement 示例:

    class ApplicationController < ActiveRecord::Base
      include SslRequirement
    end
    
    class SessionController < ApplicationController
      ssl_required :new, :create
    
      def new
        # Non-SSL access will be redirected to SSL
      end
    end
    

    force_ssl 示例:

    class SessionController < ApplicationController
      force_ssl :only =>  :new, :create
    
      def new
        # Non-SSL access will be redirected to SSL
      end
    end
    

    【讨论】:

    • force_ssl 确实很可爱,我唯一的问题是在开发模式下你不能使用它。事实上,它被“烘焙”到金属中,它只会在你处于生产模式时切换协议,所以你甚至无法用它进行测试。我不确定这个决定背后的原因,但是,这是一个可怕的决定。话虽如此,如果不是因为那个警告,我确实会使用 force_ssl,但是,很糟糕。
    • 您必须在本地配置生产模式主机。您可以使用 apache 设置乘客以运行生产模式,或者查看本指南关于使用 Pow with SSL 我假设您在 mac osx 上运行。
    • 我接受了这个答案,因为我不可避免地选择了force_ssl。但是,我的重定向问题只有在我纠正了虚拟主机的 Apache 错误配置后才消失,我在下面自己的回答中提到了这一点。 force_ssl 困扰我是因为我之前所说的原因,没有理由将其仅限于生产,这应该完全取决于开发人员。我刚刚决定不值得在本地 SSL 支持上浪费时间。现在我唯一的问题是确保只有那些我希望被加密的页面保持在 HTTPS 协议下,否则 HTTP。
    【解决方案2】:

    如果您可以访问网络服务器配置并且每个页面都应该在 HTTPS 连接之后,我建议不要在应用层使用 SSL 处理。这是为什么呢?

    当您在开发一个简单的应用程序时,没有理由在应用程序和外部之间使用负载平衡器。但是,当您需要管理负载平衡并拥有备份环境时,负载平衡器 是一种解决方案。

    由于 SSL 握手和签名请求需要 CPU 周期,负载均衡器可以在没有 SSL 的情况下与每个内部网络服务器通信,但在外部。

    如果您的应用程序正在增长,请将环境的某些部分视为。每一层都有责任。只有当你愿意的时候,混合责任才能占据一席之地。

    【讨论】:

    • 我总是更喜欢 Web 服务器来配置 SSL 支持。到目前为止,它的速度要快得多,所以我同意这种说法。在我的特定情况下,我只希望需要安全的页面将 HTTPS 作为活动协议。只是好的做法:)
    【解决方案3】:

    嗯,答案或多或少是虚拟主机配置错误。 NameVirtualHost 指令分散在各个文件中,每个文件都配置了自己的虚拟主机。此后,我将所有 NameVirtualHost 指令合并到一个文件中,该文件在加载任何单个虚拟主机之前加载。

    其中一个虚拟主机实际上使用了错误的命名主机。具体来说,暂存环境和开发/测试环境都安装在本地,但显然是在不同的 URL 下访问的。一个是在/etc/hosts 中配置的http://data.localhost/,另一个是http://data.domain.name/。所以前者解析为 127.0.0.1,而另一个解析为 192.168.x.x。但是,两个虚拟主机都试图解析到 127.0.0.1,所以很明显这是破坏性的。我刚刚为每个主机配置指定了正确的命名主机并重新启用了重写规则,并且在访问登录页面时从 HTTP 重定向到 HTTPS 一切都很好,反之亦然,以访问所有其他页面。

    TL;DR您可能应该始终拥有一个包含所有 NameVirtualHost 指令的文件,并确保在所有虚拟主机之前加载该文件。它会为你省去很多很多的麻烦。还要积极考虑让你搞砸的虚拟主机是否实际上使用了正确的主机。然后,确保 ServerName 指令不会与其他虚拟主机发生冲突,您将拥有一个快乐的虚拟 Apache 家庭!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-15
      • 2023-03-09
      • 2015-12-11
      • 1970-01-01
      • 1970-01-01
      • 2017-03-26
      相关资源
      最近更新 更多