简体   繁体   English

重定向到HTTPS时在Rails中进行多次重定向

[英]Multiple redirects in rails when redirecting to HTTPS

The situation is as follows (I am using Rails 3.1). 情况如下(我正在使用Rails 3.1)。

I have the following route: 我有以下路线:

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

Pretty standard. 很标准。 I also have this redirect rule in my Apache virtual hosts file: 我的Apache虚拟主机文件中也有此重定向规则:

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

When I navigate to https://hostname.dom/login I get a 301 status code from my browser (too many redirects). 当我导航到https://hostname.dom/login时,我从浏览器中获取了301状态代码(重定向过多)。 Can someone point out what's going on behind the hood here? 有人可以指出这里引擎盖后面发生了什么吗? Thanks. 谢谢。

I would handle this redirect through rails instead of apache. 我会通过Rails而不是Apache处理重定向。 Less chance of errors and Removes coupling of your rails app to a certain web server(apache in this case). 减少出错的机会,并消除了Rails应用程序与特定Web服务器(在这种情况下为Apache)的耦合。
For Rails 3.0.X and previous use SSL_Requirement and for 3.1.X and later use it's baked in ' force_ssl ' method. 对于Rails 3.0.X和更低版本,请使用SSL_Requirement ;对于3.1.X和更高版本,请使用“ force_ssl ”方法进行烘焙。

ssl_requirement example: 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 example: force_ssl示例:

class SessionController < ApplicationController
  force_ssl :only =>  :new, :create

  def new
    # Non-SSL access will be redirected to SSL
  end
end

I'd suggest do not use SSL hanldling on Application layer if you have an access to webserver configuration and every page should be behind the HTTPS connections. 如果您可以访问Web服务器配置,并且每个页面都应位于HTTPS连接之后,建议不要在应用程序层上使用SSL处理。 Why is that? 这是为什么?

While you are working on a simple application, no reasons to have load balancer between the application and outside. 在处理简单应用程序时,没有理由在应用程序和外部之间使用负载平衡器。 But when you should manage load balancining and have backup environment, the Load balancer is a solutuon. 但是,当您应该管理负载平衡并拥有备份环境时, 负载平衡器是一个解决方案。

Since SSL handshake and sign request takes CPU cycles, the Load Balancer can talk to each internal webserver without SSL, but the outside. 由于SSL握手和签名请求需要占用CPU周期,因此负载均衡器可以与每个内部Web服务器通信,而无需SSL,但可以与外部通信。

In case of your application is growing , think about parts of environment as layers . 如果您的应用程序正在增长 ,请将环境的各个部分视为层次 Each of layers has responsibility. 每个层都有责任。 Mix of responsibility can take a place only if you want you do. 只有在您愿意时,才有责任混合。

Well, the answer was more or less a miss-configuration of the virtual hosts. 好吧,答案或多或少是虚拟主机的配置错误。 There were NameVirtualHost directives spread out literally everywhere in separated files that each configured their own virtual hosts. 实际上,NameVirtualHost指令分散在各个文件中,每个文件都配置了自己的虚拟主机。 I have since consolidated all of the NameVirtualHost directives into a single file that loads before any single virtual host is loaded. 从那以后,我将所有NameVirtualHost指令整合到一个文件中,该文件在加载任何单个虚拟主机之前就已加载。

One of the virtual hosts was actually using the wrong named host. 其中一台虚拟主机实际上使用了错误的命名主机。 Specifically, both the staging environment and development/testing environment are installed locally, but are accessed under differnet URLs obviously. 特别是,暂存环境和开发/测试环境都安装在本地,但是显然可以通过不同的URL进行访问。 One was http://data.localhost/ configured in /etc/hosts and the other was http://data.domain.name/ . 一个是在/ etc / hosts中配置的http://data.localhost/ ,另一个是http://data.domain.name/ So the former resolves to 127.0.0.1 and the other resolves to 192.168.xx However, both the virtual hosts were trying to resolve to 127.0.0.1, so obviously that was breaking things. 因此,前者解析为127.0.0.1,而另一解析为192.168.xx。但是,两个虚拟主机都试图解析为127.0.0.1,因此很显然是很麻烦的事情。 I just specified the correct named hosts for each host configuration and re-enabled the rewrite rules and all was well with redirection from HTTP to HTTPS when accessing the login page, and vice versa for accessing every other page. 我只是为每种主机配置都指定了正确的命名主机,并重新启用了重写规则,访问登录页面时从HTTP重定向到HTTPS都非常顺利,反之亦然。

TL;DR you should probably always have a single file that has all of your NameVirtualHost directives, and ensure this is loaded before all of your virtual hosts. TL; DR您可能应该始终拥有一个包含所有NameVirtualHost指令的文件,并确保在所有虚拟主机之前加载该文件。 It will save you many, many a headache. 它将为您节省许多麻烦。 Also actively think about if your virtual host that is screwing you up is actually using the correct host. 还应积极考虑使您陷入困境的虚拟主机实际上是否使用了正确的主机。 Then, ensure that the ServerName directive is not causing conflict with other virtual hosts, and you will have a happy virtual Apache family! 然后,确保ServerName指令不会引起与其他虚拟主机的冲突,并且您将拥有一个幸福的虚拟Apache系列!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM