Rails6でapiを書くときのcorsの設定での躓きについて


この記事で書くこと

以下のようなアプリケーションを作ろうとしたときに、CORSの設定で本番反映後にエラーが発生してしまったので、同じミスをしないように情報をきちんとまとめておく。

結論

firebaseでホスティングされたnuxtアプリケーションのurlが、 https://xxxx.web.app だった場合、

config/environments/production.rb
Rails.application.configure do
  # 中略
  config.hosts << 'xxxx.web.app'
end
config/initializer/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    if Rails.env.production?
      origins 'https://xxxx.web.app'
    else
      origins 'http://localhost:3000'
    end
    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end

何が起きたか

Access to XMLHttpRequest at 'API側のurl' from origin 'アプリ側のurl' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

apiへリクエストがエラーになってしまう。

うまく行ってなかったときの状況

Ruby: 2.7.1
Rails: 6.0.3.3
rack-cors: 1.1.1

rack-corsの設定

config/initializer/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    if Rails.env.production?
      origins 'https://xxxx.web.app/'
    else
      origins 'http://localhost:3000'
    end
    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end

config/environments/production.rb

Railsガイド

config/environments/production.rb
Rails.application.configure do
  # 中略
  config.hosts << 'https://xxxx.web.app'
end

なぜ???間違ってないはず。。。
となったが、firebaseの
Hosting URL: https://xxxx.web.app という記述を見直していると最後の /がないのでは!????と気づく。

config/initializer/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    if Rails.env.production?
      origins 'https://xxxx.web.app' # 最後の/を削除する
    else
      origins 'http://localhost:3000'
    end
    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end
Access to XMLHttpRequest at 'API側のurl' from origin 'アプリ側のurl' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

そうすると、corsのエラーがなくなった。

戦いはまだ終わってなかった。

次は、apiがstatus403で返ってきた。

config/environments/production.rb
config.hosts << 'xxxx.web.app'

「こうだよ!!」とresponseで親切に教えてくれていました。。。 ありがとう、、