简体   繁体   English

人们如何测试rails 3.1 + force_ssl?

[英]How are people testing rails 3.1 + force_ssl?

The force_ssl function in rails 3.1 is hardcoded to ignore the development environment, but not test. rails 3.1中的force_ssl函数是硬编码的,以忽略开发环境,但不进行测试。 This is giving me redirect errors in my (minitest) tests. 这给了我(minitest)测试中的重定向错误。 Is the solution to set up my test server to support ssl (if so, how?). 解决方案是设置我的测试服务器以支持ssl(如果是这样,如何?)。 If not, should I monkey patch force_ssl to ignore requests in test? 如果没有,我应该修补force_ssl来忽略测试中的请求吗?

 def force_ssl(options = {})
        host = options.delete(:host)
        before_filter(options) do
          if !request.ssl? && !Rails.env.development?
            redirect_options = {:protocol => 'https://', :status => :moved_permanently}
            redirect_options.merge!(:host => host) if host
            flash.keep
            redirect_to redirect_options
          end
        end
  end

EDIT Found this chain, which confirms other people think this an issue, but doesn't look like there's a committed fix yet: https://github.com/rails/rails/pull/2630 编辑找到这个链,这证实了其他人认为这是一个问题,但看起来还没有一个承诺修复: https//github.com/rails/rails/pull/2630

Another option instead of monkey patching the entire application is to just override force_ssl in your test suite alone. 另一个选择而不是猴子修补整个应用程序只是仅在您的测试套件中覆盖force_ssl For example, in test/test_helper.rb you can add this: 例如,在test/test_helper.rb您可以添加:

# We don't want SSL redirects in our test suite
module ActionController::ForceSSL::ClassMethods
  def force_ssl(options = {})
    # noop
  end
end

Here's another approach, if you don't want to mess with monkey-patching... you can use a before filter. 这是另一种方法,如果你不想搞乱猴子修补......你可以使用前过滤器。 This is rspec, not minitest syntax, but you get the idea: 这是rspec,而不是最小的语法,但你明白了:

before(:each) do
  request.env["rack.url_scheme"] = "https"
end

This convinces your controller that it got an SSL request. 这使您的控制器确信它收到了SSL请求。

A benefit of taking this approach is that you can actually write a test to ensure your controller requires SSL. 采用这种方法的好处是您可以实际编写测试以确保您的控制器需要SSL。 :) :)

If you are interested in testing with varying SSL, I did this on the setup of the functional test. 如果您对使用不同的SSL进行测试感兴趣,我会在功能测试的设置上做到这一点。

def setup
  @request.env['HTTPS'] = 'on'
end

That's what I ended up doing after recently upgrading to Rails 3.1 and switching to the force_ssl filter. 这是我最近升级到Rails 3.1并切换到force_ssl过滤器后最终做的事情。 Monkey patch to the rescue! 猴子补丁救援!

In a new file at config/initializers/ignore_force_ssl_in_test.rb config/initializers/ignore_force_ssl_in_test.rb的新文件中

module ActionController
  module ForceSSL
    module ClassMethods
      def force_ssl(options = {})
        before_filter(options) do
          if !request.ssl? && !Rails.env.development? && !Rails.env.test?
            redirect_to :protocol => 'https://', :status => :moved_permanently
          end
        end
      end
    end
  end
end

What worked for me is similar to Kelly Sutton's . 对我有用的是与Kelly Sutton相似 I monkey patches force_ssl to ignore ssl requests in test environment, otherwise use the original rails implementation: 我在测试环境中使用补丁force_ssl来忽略ssl请求,否则使用原来的rails实现:

module ActionController
  module ForceSSL
    module ClassMethods
      alias_method :original_force_ssl, :force_ssl

      def force_ssl(options = {})
        unless Rails.env.test?
          original_force_ssl(options)
        end
      end
    end
  end
end

This approach of Simon Carletti's works nicely: http://www.simonecarletti.com/blog/2011/05/configuring-rails-3-https-ssl/ Simon Carletti的这种方法非常有效: http//www.simonecarletti.com/blog/2011/05/configuring-rails-3-https-ssl/

# config/application.rb
module MyApp
  class Application < Rails::Application
    config.force_ssl = true
  end
end

# config/environments/test.rb
MyApp::Application.configure do
  config.force_ssl = false
end

If you are looking for an answer in 2013. You can simply do: 如果您正在寻找2013年的答案。您可以这样做:

force_ssl if: :ssl_configured?

  def ssl_configured?
    !Rails.env.test?
  end

Source: http://edgeapi.rubyonrails.org/classes/ActionController/ForceSSL/ClassMethods.html 资料来源: http//edgeapi.rubyonrails.org/classes/ActionController/ForceSSL/ClassMethods.html

force_ssl unless Rails.env.test?

You can make test calls to app using ssl! 您可以使用ssl对应用程序进行测试调用!

  • use full uri with protocol https://eample.org/my/route/here in get 'https://eample.org/my/route/here' 使用完整的uri与协议https://eample.org/my/route/here get 'https://eample.org/my/route/here'
  • or use https!(true) and https!(false) to dynamically change behavior in INTEGRATION TEST 或使用https!(true)https!(false)动态更改INTEGRATION TEST中的行为

     https!(true) get "/users" https!(false) 

For CONTROLLER you do not have to use SSL, because (I think) they directly call action as method, without routing and other transfer stuff. 对于CONTROLLER,您不必使用SSL,因为(我认为)他们直接将action视为方法,而不需要路由和其他传输。

Rails docs recommend using if: ssl_configured? Rails文档建议使用if:ssl_configured? with the force_ssl call. 使用force_ssl调用。 You can then do: 然后你可以这样做:

   def ssl_configured?
    !Rails.env.development? && !Rails.env.test?
   end

Without having to monkey patch as official answer indicates. 正如官方答案所示,无需猴子补丁。

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

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