HTML5のCORSについて調べる機会があったので纏めました。
(誤りなど有りましたらコメントいただけると幸いです)
同一オリジンポリシー (Same-Origin Policy)
同一オリジンポリシーとは
同一オリジンポリシー (Same-Origin Policy) とは、リソースの保護範囲を決定する取り決めである。
セキュリティ上の理由から、ブラウザは異なるオリジンへのリクエストを送信できないように制限している。
※ 備考:なぜ制限する必要があるのか
具体例として、ブラウザから悪意ある攻撃者のサイトにアクセスし、ページのJavaScriptが実行されるとする。
同一オリジンポリシーが無いと、JavaScript から異なるオリジン (例えば file://127.0.0.1/ など) にアクセスできてしまう可能性がある。
すると攻撃者のサーバーへデータを漏出させることが容易となってしまう為、許可しない限りは異なるオリジンへの通信を制限すべきである。
同一オリジンとは
リソースのURLのうち「スキーム、ホスト、ポート」の組み合わせをオリジンと呼ぶ。
閲覧中のWebページとリソースのオリジンが一致していれば同一オリジンとみなす。
具体例として http://www.example.com に対しては、
- http://www.example.com/example.png // 一致
- https://www.example.com/example.png // スキーム不一致
- http://www2.example.com/example.png // ホスト不一致
- http://www.example.com:3000/example.png // ポート不一致
となる。
※ 備考:InternetExplorer の例外
IE に於いては以下の例外があるため注意が必要
- 信頼済みサイト(IE独自機能)に登録されているサイトは同一オリジンとみなす
- 異なるポートでも同一オリジンとみなす
同一オリジンポリシーによる制約
以下の WebAPI は同一オリジンポリシーの制約を受ける。
- XMLHttpRequest
- Canvas
- Web Storage
- X-Frame-Options
また以下のHTML要素などによる異なるオリジンからのリソース取得については制約を受けない。
- script // スクリプト
- img, video, audio // メディア
- object, embed, applet // プラグイン
- frame, iframe // 別サイトのコンテンツ
- link, CSS(font-face): // CSS、Webフォントなど
CORS (Cross-Origin Resource Sharing)
CORSとは
CORS (Cross-Origin Resource Sharing) は異なるオリジン間でデータをやり取りするための決まり。
CORSによって異なるオリジンから読み出されたリソースも、同じオリジンから読み出されたリソースと同じように扱うことができる。
例えば XHR (XMLHttpRequest) を利用すれば Ajax で異なるオリジンのリソースを取得することが出来る。
しかし XHR は同一オリジンポリシーに従うため、異なるオリジン間へのリクエストが制限されている。
CORSを行うためには、サーバーとクライアント双方で適切なヘッダーを付与する必要がある。
CORSに関連するリクエストヘッダ
リクエストヘッダーはブラウザが自動的に付与してくれる。
- Origin: オリジン情報(必須)
- Access-Control-Request-Method: HTTP メソッドの種類
- Access-Control-Request-Headers: リクエストヘッダの種類
CORSに関連するレスポンスヘッダ
レスポンスヘッダーは必要に応じて付与する必要がある。
- Access-Control-Allow-Origin: 許可するオリジン(必須)
- Access-Control-Allow-Credentials: 認証情報を含むリクエストの許可
- Access-Control-Allow-Methods: 許可する HTTP メソッドの種類
- Access-Control-Allow-Headers: 許可するリクエストヘッダの種類
- Access-Control-Expose-Headers: 要求するリクエストヘッダの種類
- Access-Control-Max-Age: プリフライトリクエスト(OPTION)の有効期限
crossorigin 属性 と Canvas 要素
crossorigin 属性とは
HTML5 では以下の HTML 要素が crossorigin 属性に対応している。
- img
- audio
- video
- link
- script
これらの HTML 属性に crossorigin 属性が付与すると、リソース取得時のリクエストヘッダーが変化する。
- なし: CORSに対応しない
- crossorigin (値指定なし): anonymous と同一
- crossorigin="anonymous": 認証情報を付与しない
- crossorigin="use-credentials": 認証情報を付与する
Canvas 要素の機能制限
異なるオリジンのリソースを Canvas 要素で読み込んだ場合、同一オリジンポリシーによる 制約によって、以下の関数などが実行できなくなってしまう。
上述の crossorigin 属性を指定することで、これらの関数を利用することができるようになる。
- toBlob() // 描画内容からblobオブジェクトを生成
- toDataURL() // 描画内容からbase64を生成
- getImageData() // 指定範囲のImageDataオブジェクトを取得
資料
- 同一オリジンポリシー
- HTTP アクセス制御 (CORS)
- CORS 設定属性
- CORS Enabled Image