2021-08-26

Cross Origin Resource Sharing(CORS)について

日頃仕事をする中で、意外とこのブログに書いた記事が新人教育の時などに役に立つことが多いので、知っていることでもきちんと記事にまとめておくと便利ということがわかった
なので今回はたまーに遭遇するCORSについて記事にしておこうと思う

あと、いつブログ書く気力なくなるかわからないので、少しでも書く気力があればバンバン記事にしておくのが良いと思った

Cross Origin Resource Sharing(CORS)とは

  • Cross Origin Resource Sharing の略で、オリジン間リソース共有に関する指示をブラウザに行うための仕組み
  • 簡単に言うと、ブラウザで閲覧しているページと違うオリジンからのリソースの取得を許可するための仕組み
    • 例えば https://hoge.com をブラウザで見ていて、そのページ内で https://hoge2.com からデータを取得しようとした場合に、https://hoge2.comhttps://hoge.com からリソースの取得を許可していない場合はブラウザに止められるというもの
    • 他のサーバーから取得したデータが、任意のコードを実行してしまうなどのセキュリティ上の問題があるためCORSが存在している
    • MDN Web Docsの図がわかりやすい
  • CORSはブラウザ実装の話なので、サーバー同士の通信では関係ない
    • CORS許可されていないサーバーにヘッダ偽装してcurlでリクエスト投げてもレスポンスは200となる
    • curl -X GET -I -H "Origin: https://hoge.com" https://example.com
  • CORSを設定することで他のサーバーからも自由にデータを取得できるようになるので、セキュリティのリスクはむしろ増える
  • CORS対応はデータを呼ばれる側(リクエストを受ける側)で行う
    • 例えばAWSのS3とかCloudFrontとか
    • APIモードのRails(localhost:3000)にReactアプリ(localhost:4000)からアクセスしたい場合は、Rails側にrack-cors gemなどを入れて対応する必要があるということ

具体的にCORS設定が行われている例として、郵便番号から住所情報を返してくれる郵便番号APIというサイトでリクエストを投げてみる↓と

curl -X GET -I https://madefor.github.io/postal-code-api/api/v1/220/0005.json

HTTP/2 200
server: GitHub.com
content-type: application/json; charset=utf-8
access-control-allow-origin: *
.
.
.

と言った感じで access-control-allow-origin: * がレスポンスヘッダに付与されている(付与してくれている)
なのでRailsなどに組み込んでも、特に設定などなくAPIを叩くだけで使うことができる

CDNとか色々挟んでいると、誰にCORS設定すればいいのかわからなくなることがあるので、アプリ構成を正しく把握することが大切
Rails + CloudFront + GAEという構成のときに、CloudFrontのCORS設定だけではなく、GAEのhandlersでCORS設定しないといけない場合があった
https://cloud.google.com/appengine/docs/standard/go/config/appref?hl=ja#handlers_element

参考ページ