CORS(オリジン間リソース共有)とは?

はじめに

こんにちは、フロントエンドチームの高田(@proghallelujah)です。 webアプリケーションを開発していると、このような内容のエラーが出たことがある人は多いかもしれません

Access to XMLHttpRequest at 'https://hoge.com' from origin 'https://fuga.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

このエラーは一体どういったことを伝えているのでしょうか?また、エラー文内にあるCORSというものは一体なんでしょうか?今回はこちらについて解説していこうと思います。

CORSについて

CORSの意味

まず、このCORSというのはCross-Origin-Resource-Sharingの略で、日本語に訳すとオリジン間リソース共有と言います。

このCORSは、あるオリジンで動作しているウェブアプリケーションに、異なるオリジン内のリソースへのアクセスをオリジン間HTTPリクエストにより実行するようブラウザに指示するための仕組みです。


(補足)オリジンとは?

プロトコルドメイン、ポートによって定義されたものです。

例) http://hoge.com:80

こちらの場合、http(プロトコル)+hoge.com(ドメイン)+80(ポート)からできたオリジンです。


なぜCORSが必要か?

CORSは、webセキュリティポリシーの一つSame-Origin Policy(同一生成元ポリシー)によって定められた制限に対応しており、安全なオリジン間のリクエストやブラウザ・サーバー間のデータ転送を行うためのものです。

同一生成元ポリシーとは?

JavaScriptなどのプログラムを用いた通信において、そのプログラムが存在する同一のオリジン内でのみデータアクセスを可能にし他のオリジンへのアクセスをできないよう制限するための仕組みです。

オリジン1: http://hoge.com/dir/page.html
オリジン2: http://hoge.com/dir/shop/main.html

パスは異なっていますが、プロトコル、ドメインといったオリジンは同一のため、アクセスは可能となります
オリジン1: http://hoge.com/dir/page.html
オリジン2: https://hoge.com/dir/page.html

パスは同一ですが、プロトコルが違うため、アクセスは制限されます

なぜ制限するのか?

例えばXSS(クロスサイトスクリプティング)という攻撃手法があります。これは標的とするwebアプリに第三者が外部から悪意のあるスクリプトを埋め込み、アプリが意図をしていない動作を引き起こすようにします。

これは基本的に別のオリジンからの攻撃になるため、同一制限ポリシーがあることで防ぐことができます。

このように異なるオリジンからのアクセスを制限することにより、元オリジンのリソースに対して悪い影響を与えることを防ぐのを目的としています。

制限が適用されないケース

基本的にはJavaScriptによる非同期通信などに適用されますが、htmlベースのものでは制限されないものが多いです

  • <img>タグのsrc属性で読み込まれた画像
  • <link>タグのhref属性で読み込まれたCSS
  • <script>タグのsrc属性で読み込んだJavaScript

などなど、普段よく使っているものの中にも別のオリジンから読み込んでいるものが多くありますが、これらは同一オリジンポリシーが適用されません。

参考

MDN - オリジン間リソース共有 (CORS)

CORS(Cross-Origin Resource Sharing)

MDN - Origin (オリジン)

MDN - 同一オリジンポリシー

Wikipedia - クロスサイトスクリプティング