Rails
CORS

RailsでCORSについて学ぶ_100DaysOfCodeチャレンジ9日目(Day_9:#100DaysOfCode)

はじめに

この記事はTwitterで人気のハッシュタグ#100DaysOfCodeをつけて、
100日間プログラミング学習を続けるチャレンジに挑戦した9日目の記録です。

動作環境

  • ruby 2.4.1
  • Rails 5.0.1

現在学習している内容のリポジトリ

https://github.com/yuta-ushijima/notebook-api-on-rails

本日学んだこと

  • CORSの概要
  • config/initializers/cors.rbの設定

CORSとは?

Cross Origin Resource Sharing(クロスオリジンリソースシェアリング)の略。オリジンというのは、スキーマ・リソース・ポートを組み合わせてできているURLのこと。

例えば、https://www.yuta-u.comというURLがあった場合、次のような構成でオリジンが構成されていることになります。

  • https...スキーマ
  • www.yuta-u.com...リソース
  • 443...ポート(HTTPSのポートはデフォルトで443)

そのオリジンをクロスしてリソースをシェアリングする、つまり違うオリジン(URL)からのアクセスがあってもデータを取得できるようにすることです。(逆に言えれば、許可していないオリジンからのアクセスは遮断することになります)

通常は同じオリジン(URL)からでなければデータの取得はできませんが、CORSを設定していればオリジンが違ってもGETやPOSTなどのHTTPメソッドを使ってデータを取得したり作成できるようになるということですね。

使いどころ

フロントエンドとバックエンドでドメインが異なる場合は、設定の必要があり。例えば、ReactでSPAを作ってAPIサーバーをRailsで立てている場合、それぞれが違うURLだとCORSを設定しないとデータの取得ができない。

RailsでCORSの設定をする

Railsを新規作成した際に、GemfileにはいくつかのコメントアウトされたGemがあると思います。

今回使用するrack-corsもデフォルトでコメントアウトされているGemなので、これを外します。

gem 'rack-cors'のコメントアウトを外した後にbundle installすると、自動的にconfig/initializers/cors.rbが作成されるのでファイルを開きましょう、。

# デフォルトの状態

# Be sure to restart your server when you modify this file.

# Avoid CORS issues when API is called from the frontend app.
# Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin AJAX requests.

# Read more: https://github.com/cyu/rack-cors

# Rails.application.config.middleware.insert_before 0, Rack::Cors do
#   allow do
#     origins '*'

#     resource '*',
#       headers: :any,
#       methods: [:get, :post, :put, :patch, :delete, :options, :head]
#   end
# end

以下コードのコメントアウトを外します。

Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    origins 'example.com'

    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end

その後、bundle exec rails sでサーバーを立ち上げてましょう。

なお、すでにRails serverが立ち上がっていた場合には一度再起動する必要がありますので注意。

テストサイトでCORSの実験

手軽にCORSを試せるサイト、Rest test test...にアクセスして実験してみます。

https://resttesttest.com/

まずはconfig/initialisers/cors.rbのoriginsの部分をアスタリスクに変更し、全てのoriginsからアクセスを許可します。

# config/initialisers/cors.rb
(中略)
- origins 'example.com'
+ origins '*' 
(中略)

対象のURLを貼り付けてAJAXのボタンを押すと、HTTP 200で取得に成功しているのがわかるかと思います。

cors-001.png

参考サイト

https://qiita.com/IzumiSy/items/c10949e9a00d1c61613c

https://github.com/cyu/rack-cors

https://dev.classmethod.jp/cloud/cors-cross-origin-resource-sharing-cross-domain/

https://til.hashrocket.com/posts/4d7f12b213-rails-5-api-and-cors