CORSについて

調査の動機

Rails(Framewrok)のおかげで開発している上で気にしなくてはならない部分を随分と負担してもらっているということに気がついた。 webアプリケーションはインターネットがあって成り立っているので、最終的な目標であるサービスを提供するという事を実現するためにはrailsだけでなくプラットフォーム側の制約や問題にも対処できるように理解を深めなければならないと考えました。

概要

CORS Cross Origin Resource Sharingの略 
厳密ではないがイメージとして以下のようなドメインを用意した時

ユーザはAのドメインにアクセスしている時にBのドメインとデータのやり取りを行うことができる。

CORSを理解するのに必要そうなキーワード

  • SOP Origin
  • Origin

Originとは?

まずはじめにOriginとは何か?

  • スキーム
  • ドメイン
  • ポート
    の三つをまとめたURIをOrigin(生成源)と呼ぶ

オリジンの比較

http://example.org
と以下の4つのオリジンを比べた時に同じoriginになるのは2番目のオリジンだけになる。(httpのデフォルトポートが80番のため)
それ以外はスキーム,ドメイン,ポートが異なっているため全て別のオリジンとしてみなされる。

SOP

same origin policyの略
抽象的に説明を行うとブラウザーはアクセスしたオリジンを信頼する。その信頼がある限りはサーバーにデータを送信することも受信することも可能であるし、オリジンに基づいてDOMのプロパティを読み取ったり書き換えたりすることができる。

基本的にはこの原則がwebのセキュリティーを高めてい、例外を除いて別のオリジンとリソースのやり取りを行えなかったり、プロパティを操作する事は出来無くなっている。

CORSの利用

SOPに例外を許す方法としてCORSを利用する。

  • 別のオリジンからGETメソッドをつかってリソースを取得する時
  • GET以外のメソッドを利用して異なるオリジンとリソースのやり取りを行う時
  • 認証情報やcookieをリクエストに含んだ時

今回は一番上のGETメソッドを利用したリソースの共有について
Access-Control-Allow-Origin: "アクセスを許可したオリジン" or "*"(全てのオリジン)
のような形でHTTPヘッダをレスポンスのヘッダにつけて返すだけでCORSが成立する。

上記のA,Bのドメインを例にAというドメインからBのリソースを共有しようと考えると
Access-Control-Allow-Origin: "http://example.org"
をBのサーバで付与してレスポンスを返す。

またAだけでなく全てのオリジンに対してリソースの共有を行いたい場合は,
Access-Control-Allow-Origin: "*"
と全てのオリジンを許可するワイルドカードを利用することで実現できる。

ヘッダーを付与する方法はappachやnginxで付与する方法もあれば、frameworkで付与する方法もある。

まとめ

CORS自体の処理はそんなに難しくはないが、CORSの背景がCORSのハードルを上げているような気がする。CORSはただ単にアクセスしているオリジンと異なるオリジンとリソースのやり取りを行うための仕様でその方法はヘッダを介して実現されている。

参考文献