今回達成すること
-
同一オリジンポリシーとCORSを理解して、
-
RailsにGem
rack-cors
を導入しCORS設定を行います。
この記事を完走してHelloを返すアプリケーションを完成させましょう。
※ この記事ではRails(apiディレクトリ内)のファイルを編集します。
現状の確認
コンテナを起動してブラウザからhttp://localhost:8080にアクセスしてください。
root $ docker-compose up
デベロッパーツールも開いておきましょう。
前回作成したボタンを押すと。。。あれ。エラーが返ってきますね。
CORSって何!?
CORSを理解する前に、このエラーの原因について理解しましょう。
っと。その前にコンテナを削除しときましょう。
root $「control」+「C」
root $ docker-compose rm -f
エラーの原因
画像のエラーは、ブラウザに備わっている同一オリジンポリシーに違反していることで吐き出されたエラーです。
同一オリジンポリシーとは
あるオリジンから読み込まれた文書やスクリプトについて、異なるオリジンからアクセスできないように制限した規約です。
オリジンとは
- スキーム(http)
- ドメイン(example.com)
- ポート(8080)
が組み合わさったものを言います。
今回のケースだと「http://localhost:8080」と「http://localhost:3000」をそれぞれ一つのオリジンとみなします。
つまり?(まとめ)
今回のエラーの原因は、
- http://localhost:3000/api/v1/hello (オリジン)から読み込まれた
- Hello(文章やスクリプト)について
- http://localhost:8080(異なるオリジン)から
- アクセスできないように制限されているため
発生したのです。
(参考)オリジンの具体例
同一オリジンポリシーに違反していない。
- スキームとドメインが一致しているので同一オリジン
- http://example.com/app1/index.html
- http://example.com/app2/index.html
- http://example.com/category/app1/index.html
同一オリジンポリシーに違反している。
-
スキームが異なるオリジン
- http: //example.com/app1
- https: //example.com/app2
-
ドメインが異なるオリジン
- http://example.com
- http://www.example.com
-
ポートが異なるオリジン
- http://example.com
- http://example.com:8080
参考
CORSとは?
エラーの原因が理解できたところでCORSについて説明します。
CORSとは、Cross-Origin Resource Sharing(クロスオリジンリソースシェアリング)の略で、異なるオリジン間の通信を許可する仕組みです。
上で説明した同一オリジンポリシーは、不正なやりとりを防止すると同時に正当なやりとりも拒否します。
その回避策として用意されているのがこのCORSです。
CORS設定の方法
2つあります。
-
Nuxt.js側にproxy(代理サーバ)を立てて通信を行う方法
-
Rails側でリクエストがくるドメインを許可する方法
ただ1の方法はDockerコンテナ経由だとうまくいかなかった。。。
そこで2のRailsにドメインの許可をする方法で設定していきます。
RailsにGem rack-corsを導入する
Railsに rack-cors
を導入し、指定したドメインのアクセスを許可します。
Gemのインストール
「api」ディレクトリの
26行目付近のgem 'rack-cors'
のコメントを外します。
api/Gemfile
# コメント外す
gem 'rack-cors'
root $ docker-compose build api
Railsを動かすDockerfileには、$ bundle install
が実行されるように記述していますので、ビルドと同時にGemもインストールされます。
ビルドが完了したらrack-cors
がインストールされているか確認します。
root $ docker-compose run --rm api bundle info rack-cors
rack-cors (1.1.1)
...
OKですね。
設定ファイルの編集
続いてrack-cors
の設定ファイルを編集していきましょう。
「api/config/initializers」直下にある
コード部分のコメントを外してorigins
の部分を書き換えます。
api/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 ENV["API_DOMAIN"] || ""
resource '*',
headers: :any,
methods: [:get, :post, :put, :patch, :delete, :options, :head]
end
end
ENV["API_DOMAIN"] || ""
...ENV["API_DOMAIN"]
の中にはdocker-compose.ymlで指定した値が入っています。|| ""
... ここにNullが入るとエラーになります。そこで環境変数が存在しない場合は空文字を入れるようにしています。
docker-compose.yml
api:
...
environment:
API_DOMAIN: "localhost:$FRONT_PORT" # この値がENV["API_DOMAIN"]に入る
これでrack-cors
の設定は完了です。
エラーが解決したか確認しよう
それではコンテナを起動して、ブラウザで確認してみましょう。
root $ docker-compose up
ボタンを押すと。。。
Helloが表示され、レスポンスの成功を表す200番も返ってきています。
やった。成功です。
嬉しさのあまりコンテナを削除するのを忘れないでおきましょう。
root $ 「control」+「C」
root $ docker-compose rm -f
ここまでの変更をpushしとく
全てのディレクトリをGitHubにpushしておきましょう。
- apiディレクトリ
api $ git add -A
api $ git commit -m "add_hello_controller"
api $ git push
- frontディレクトリ
api $ cd ../front
front $ git add -A
front $ git commit -m "add_axios.js"
front $ git push
- rootディレクトリ
front $ cd ..
root $ git commit -am "finished_hello_API"
root $ git push
まとめ
さて、今回はRailsのCORS設定を行っていきました。
これで初めてのAPIアプリケーションが完成です。\ o /
このチャプターのまとめ
このチャプター「RailsAPI×Nuxt.js初めてのAPI通信」では以下のことを行ってきました。
-
RailsにGem rack-corsを導入しCORS設定を行う(今ココ)
以上でチャプター終了です。
次回は新章始まります
次回からは新章「Heroku.ymlを使ったDockerデプロイ」が始まります。
今作ったアプリケーションをネット上に公開するところまでを行います。
いざ!👇のリストへ。