Rack-cors не показывает заголовки в производственной среде для swagger-ui_rails

В настоящее время я использую пару приложений Rails 3.2.x. Тот, который использует Ruby 1.9.x и является конечной точкой API, содержит гем Rack-cors (1.0.1) - app Alice; другой запускает гем swagger-ui_rails и является приложением, содержащим документацию по API - приложение Bob. Документы Swagger были созданы с гемом Swagger-Docs, который работает в формате версии 1.2. По той или иной причине я не могу заставить приложение Алиса предоставить мне информацию для Боба из-за этой ошибки:

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 (Боб находится на 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

Когда у меня есть этот код в config/environments/development.rb в Алисе localhost подключается, и swagger-ui появляется, как и ожидалось, без ошибок в консоли.

На вкладке сети Chrome это то, что у меня есть локально (Боб и Алиса в 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

Это то, что я получаю, когда Боб в dev, а Алиса в prod:

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 никогда не возвращал мне правильные заголовки контроля доступа, как локально, так и на сервере Боба.

У prod-Bob также есть некоторые расширения EBS для добавления некоторых заголовков и методов запросов в nginx. В каком-то другом посте SO я видел людей, добавляющих заголовки ответов напрямую через Rails, и поэтому у Боба также есть следующее 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 ответ

Решение

Драгоценный камень Swagger-docs, который я использую, помещает .json файлы, которые я создал в Rails /public каталог. Таким образом, Rails видит в этом статические файлы, а не то, что должно проходить через промежуточное ПО Rack. Так как наш файл production.rb имел config.serve_static_assets = falseЭто означает, что все эти статические файлы находятся в ведении нашего веб-сервера (Apache/Nginx), а не в компетенции Rack-Cors.

После добавления некоторых заголовков CORS в Apache, swagger-ui загружался соответствующим образом, но удваивал заголовки - 1-й для Apache, 2-й для стеллажей.

С тех пор я удалил gem rack-cors и скорректировал настройку сервера Apache для Alice, основываясь на ответе SO, связанном с подстановочными поддоменами:

/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"
Другие вопросы по тегам