Rack-cors没有在swagger-ui_rails的生产环境中显示标题

时间:2017-09-22 23:24:45

标签: ruby-on-rails ruby-on-rails-3 elastic-beanstalk rack-cors

我目前正在运行几个Rails 3.2.x应用程序。使用Ruby 1.9.x并且是api端点的那个上面有Rack-cors gem(1.0.1) - app Alice;另一个运行swagger-ui_rails gem,是托管api文档的应用程序 - 应用Bob。 swagger docs是用swagger-docs gem创建的,它运行格式版本1.2。出于某种原因,由于这个错误,我无法让应用程序Alice给我Bob的信息:

Failed to load https://alice.example.com/api-docs/v1/api-docs.json:
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://bob.example.com:3000' is therefore not allowed access. 

然而!当我查看网络选项卡时,响应是200,我可以看到json信息。但响应标头肯定没有所需的Access-Control-Allow-Origin标头。

通过AWS Elastic Beanstalk(Bob托管在EBS上)和本地(带有绑定地址)都会发生这种情况。

在我的爱丽丝config/environments/production.rb中,我有以下内容:

config.middleware.insert_before 0, 'Rack::Cors' do
  allow do
    origins ->(origin, env) do
      Rails.logger.warn("CORS origin: #{origin}")
      origin =~ /\.example\.com(:\d+)?\z/
    end
    resource('*', :methods => [:get, :post, :options], :headers => :any)
  end
end

当我在Alice的config/environments/development.rb中有这个代码时,localhost连接并且swagger-ui按预期显示,并且在控制台中没有错误。

在Chrome的网络标签中,这是我本地的(Bob和Alice in dev / localhost)

Access-Control-Allow-Methods:GET, POST, OPTIONS
Access-Control-Allow-Origin:http://apitest.bob.com:3000
Access-Control-Expose-Headers:
Access-Control-Max-Age:1728000
Content-Length:1499
Content-Type:application/json
Date:Fri, 22 Sep 2017 21:44:45 GMT
Last-Modified:Mon, 28 Aug 2017 17:37:22 GMT
Server:
Vary:Origin

这是Bob在开发中并且Alice处于刺激状态时所得到的:

Accept-Ranges:bytes
Connection:keep-alive
Content-Length:1500
Content-Type:application/json
Date:Fri, 22 Sep 2017 23:10:00 GMT
ETag:"abc-559ce64fb8374"
Last-Modified:Fri, 22 Sep 2017 22:04:35 GMT
Server:

正如你所看到的,prod-Alice并没有像dev-Alice那样返回任何类型的头文件,即使使用完全相同的Rack-Cors代码块也是如此。

rake middleware在堆栈顶部显示Rack :: Cors,curl -i https://alice.example.com/api-docs/v1/api-docs.json从未在本地和Bob的服务器上为我返回正确的访问控制头。

prod-Bob还有一些EBS扩展,可以为nginx添加一些请求标头和方法。在其他一些SO帖子中,我看到人们通过Rails直接添加响应头,所以Bob在application_controller.rb中也有以下内容(在dev中,使用binding.pry,我可以确认响应肯定有指定的头)

  after_filter :set_access_control_headers

  def set_access_control_headers
    headers['Access-Control-Allow-Origin'] = Rails.configuration.hostnames['headers']
    headers['Access-Control-Request-Methods'] = 'GET, PUT, POST, OPTIONS'
  end

我有点不知所措,任何帮助或想法都会受到赞赏。

1 个答案:

答案 0 :(得分:1)

我使用的Swagger-docs gem将我创建的.json文件放入Rails' /public目录。因此,Rails将其视为静态文件,而不是应该通过Rack中间件的东西。由于我们的production.rb文件有config.serve_static_assets = false,这意味着所有这些静态文件都是我们的Web服务器(Apache / Nginx)的责任,而不是rack-cors gem的责任。

在向Apache添加一些CORS标头后,swagger-ui被正确加载,但是标头加倍 - 第一个用于Apache,第二个用于机架式连接。

我删除了rack-cors gem并根据与通配符子域相关的SO答案调整了Alice上的Apache服务器配置设置:

<强> /etc/apache2/sites-enabled/mysite.conf

SetEnvIf Origin ^(https?://.+\.example\.com(?::\d{1,5})?)$   CORS_ALLOW_ORIGIN=$1
Header append Access-Control-Allow-Origin  %{CORS_ALLOW_ORIGIN}e   env=CORS_ALLOW_ORIGIN
Header merge  Vary "Origin"
Header set "Access-Control-Allow-Methods" "GET, POST, OPTIONS"