エラー発生
フロントエンドとバックエンドを通信させた時、このようなエラーが発生したことはありませんか?
なんだかコードは間違ってなさそうだな、なんのエラーだろう、CORSって書いてある、、、と初見の人は思うと思います。
CORSって?
CORS(Cross-Origin-Resource-Sharing)オリジン間リソース共有
追加の HTTPヘッダーを使用して、あるオリジンで動作しているウェブアプリケーションに、異なるオリジンにある選択されたリソースへのアクセス権を与えるようブラウザーに指示するための仕組みです。
ふむふむ、、、
オリジンとは?
何かしないとアクセス権がないのか?
オリジン
URLの「スキーム」「ホスト」「ポート」の3つの組み合わせたものです。
同一オリジン
http://example.com/home
http://example.com/login
上記はスキームおよびホストが同じなので同一オリジンと言えます。
http://example.com:80
http://example.com/file
上記もスキーム、ホストが同じでポート番号の80番はHTTPのデフォルトのポート番号なので同一のオリジンと言えます。
同一オリジンではないもの
スキームが異なっている
https://example.com
http://example.com
ホストが異なっている
http://app.example.com
http://www.example.com
ポート番号が異なっている
http://example.com
http://example.com:5000
http://example.com:8000
エラーが発生したときは「http://localhost:3000 」と「http://127.0.0.1:5000/todos 」で通信を行おうとしていたため「オリジンが違うよ!」「CORSの設定がないよ!」と言われていたわけですね。🤔
ではなぜ、異なるオリジン間での通信がダメなのでしょう?
#同一オリジンポリシー
同一オリジンポリシーは重要なセキュリティの仕組みであり、あるオリジンによって読み込まれた文書やスクリプトが、他のオリジンにあるリソースにアクセスできる方法を制限するものです。
もし、上記のような制限がないと悪意のあるスクリプトを持ち込まれて悪さをされる可能性があります。同一オリジンポリシーはオリジン間のリソース共有に制限をかけ、webサイトの脆弱性を防いでいるのです。
しかし、制限をかけられると不便な面もあります。例えば企業が「誰でも使っていいよ〜」と公開しているREST APIのサービスをユーザーが扱いたい場合です。
上の絵のような不便さを解消するため、同一オリジンポリシーに基づく制限の解除をCORSは行ってくれます。
リクエスト制限の解除をざっくりと
クライアントサイド側
クロスオリジンのリクエストが行われるとクライアント側は自動的にHTTPリクエストにOriginというヘッダを追加してくれます。特に何かを行うことはありません。
###サーバーサイド側
サーバーサイドではAccess-Control-Allow-Originをレスポンスのヘッダに付与する必要性があります。
↑Access-Control-Allow-Originを付与した後のレスポンスヘッダ
具体的な方法は言語で異なっているのでドキュメント等で調べていただきたいです。🙇♂️
まとめ
今回は具体的な実装方法は説明してないのですが、初めてCORS関連のエラーを見たとき、「なんかこんなのあったな、制限を解除してあげればいいんだっけ」と思っていただければ躓くことはないと思います。
参考
MDN
オリジン間リソース共有 (CORS)
Origin (オリジン)
同一オリジンポリシー
JavaScript入門
CORS とは?