オリジン間リソース共有?CORSエラーを解決する時に確認すること・試すこと

ゆーたろー

こんにちは、ゆーたろーです。

HRTechベンチャーのエンジニアです。
TypeScript/Vue.js(Nuxt.js)/React/Next.js/PHP/LaravelでWebアプリケーションの開発を行っています。

・プログラミングスクールメンター
・神戸で勉強会「つながる勉強会」を運営
・神戸メインのグルメインスタ運営

など色々やっています。1児のパパです。

仕事でCORSエラーに詰まって、四苦八苦してしたのでその経験から“CORSエラーを解決するために確認すること・試すこと”をまとめておきます。

ついでにCORSについても少し説明を入れます。

「CORSとは?」についてはググればたくさん出るので、簡単な説明と参考記事の添付くらいに留めます。

この記事でわかること

  • CORSの概要
  • CORSエラーを解決するために確認すること・試すこと
目次

CORSの概要

CORSはCross-Origin Resource Sharingの略で日本語で説明される場合はオリジン間リソース共有と呼ばれます。

上記の記事の冒頭にこのように書かれています。

オリジン間リソース共有 (CORS) は、追加の HTTP ヘッダーを使用して、あるオリジンで動作しているウェブアプリケーションに、異なるオリジンにある選択されたリソースへのアクセス権を与えるようブラウザーに指示するための仕組みです。

https://developer.mozilla.org/ja/docs/Web/HTTP/CORS

簡単に言うと異なるオリジン間で通信をすること(リクエストを送る、レスポンスを返す)を許可するための仕組みです。

ちなみにオリジンとは

プロトコル + ドメイン + ポート番号

のことです。

例えば(架空ですが)、http://sample-domain.com:80。これがオリジンです。

  • http:プロトコル
  • sample-domain.com:ドメイン
  • 80:ポート番号

CORSの設定が必要になるケースは以下のケースがあります。

  • フロントエンドをバックエンドを切り離したアプリケーション(SPA/SSR/SSG)
  • 外部サービス間との通信を行う場合

異なるサービスは異なるオリジンなのでCORSの設定をうまく行わないと通信エラーになります。

CORSについてもう少し詳しく知りたい方はこちらの記事を読むことをオススメします。
とてもわかりやすかったです。

良い記事や情報がたくさんあるのでCORSの概要説明はこれくらいで終わります。

CORSエラーを解決するために確認すること・試すこと

サービス間での通信を行う場合はCORSエラーに遭遇することも多いです。

ここでは僕が業務での経験を基に

ゆーたろー

CORSエラーが解決しない場合はこの辺に原因があるかもよ?

という感じで確認すべきことや試してみるべきことをまとめます。

エラー文の例

Access to XMLHttpRequest at 'オリジン/パス' from origin 'オリジン/パス' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

CORSエラーになった場合はフロントエンドからAPIにリクエストした時にこのようなエラーがブラウザコンソールに出力されます。

全体の構成

まず、以下のようなサービスの構成だとします。

異なるオリジン間の通信は上記画像から

  1. サービスAとサービスBとの通信
  2. サービスB内のバックエンド(Laravel API)とフロントエンド(Nuxt.js)との通信

があります。

それぞれについてまとめます。

この記事ではサービス=アプリケーションと思ってください。(サービスという呼び方にした意味は特にないです。)

サービスA、サービスB間のCORS対策(添付画像中の①)

インフラレイヤーの設定

完全にお互いのサービスが独立している場合はそれぞれのサービスが存在するネットワークがそれぞれのIPアドレスからのアクセスを許可しているかどうかを確認する必要があります。

例えばどちらのサービスもAWSのサービスにデプロイしている場合、セキュリティグループで外部サービスのIPアドレスからの接続が許可されているかを確認しましょう。

また、プロトコルの指定も必要です。
(HTTPだけ許可するのか、HTTPとHTTPSどちらも許可するのかなどなど)

僕は業務で実際にこれが原因でCORSエラーを解決するためにアプリケーション内の対策ばかりに目を向けてしまい、時間を溶かした経験があります。

このようにインフラレイヤー(この言い方が正しいかは分かりませんが)に原因がある場合も。

アプリケーション内の設定

これは調べると結構出る内容ですね。

僕は普段の業務ではバックエンドにLaravelを使っているので「Laravel CORS」なんかでググるとたくさん出てくる俗に言う(?)CORS設定です。

今回は設定方法の例としてLaravelでのCORS設定を取り上げます。

まずはCORS設定用のComposerパッケージであるfruitcake/laravel-corsを導入します。

GitHubリポジトリはこちらです。

以下コマンドでパッケージをインストールします。

$ composer require fruitcake/laravel-cors

Laravelプロジェクトのconfigディレクトリにcors.phpというファイルが作成されます。

cors.phpを修正して、リクエストの許可をするパスやオリジンなどを設定することでCORS設定を行うことができます。

ゆーたろー

パッケージを使うととても簡単に設定ができますね!

設定してみてもうまくいかない場合は

'paths' => ['*'], // すべてのパスからの接続を許可

'allowed_origins' => ['*'], // すべてのオリジンからの接続を許可

このように一旦ガバガバな設定にして、うまくサービス間で通信ができるかどうかテストしてみましょう。

LaravelでCORS設定をする方法は上記で書いたパッケージの使用とは別に、ミドルウェアを作成して適用する方法もあります。

詳しい実装内容は参考記事を載せておきますので割愛します。

サービスB内のCORS対策(添付画像中の②)

アプリケーション内の設定

フロントエンドにNuxt.jsやNext.jsのフレームワーク、バックエンドにLarave、Ruby on Railsで作成してAPIで構成するアプリケーション(SPA、SSR、SSGとか)の場合は先述のアプケーション内の設定のみでCORS設定ができます。

設定方法も先ほどと同じなので割愛します。

最後に

最近アプリケーションのアーキテクチャとして採用されることが多くなっている

フロントエンドはNuxt.jsやNext.js + バックエンドはAPIのみ

の構成(SPAとかSSRとかSSGとか)や、外部サービス(アプリケーション)との通信を行う場合にはCORSエラーは付きものなのでエラーが発生した時にどういう原因が考えられるのか?を知っておくと役に立つと思います。

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!

この記事を書いた人

上場グループのHRTechベンチャーで働くWebエンジニアです。
新卒で入社した大手重工メーカを4年で退職し、2020年4月からエンジニアとキャリアチェンジしました。

仕事ではTypeScript/Vue.js(Nuxt.js)/Laravelを主に使っています。

プログラミングスクールの講師やデザイン関連のお仕事もさせてもらっています。

神戸で「つながる勉強会」という勉強会を月1で運営しています。
https://tsunagaru-kobe.connpass.com/

お仕事のご依頼、ご相談はお問い合わせページもしくはTwitterのDMからお願いします。

コメント

コメントする

目次
閉じる