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"