読者です 読者をやめる 読者になる 読者になる

ぺーぺーSEのブログ

備忘録・メモ用サイト。

CORS(Cross-Origin Resource Sharing)について

AWS API Gateway セキュリティ jQuery JavaScript

CORS(Cross-Origin Resource Sharing)は、ブラウザがオリジン(HTMLを読み込んだサーバ)以外のサーバからデータを取得する仕組み。

各ブラウザにはクロスサイトスクリプティングを防止するために、クロスドメイン通信を拒否する仕組みが実装されている。

特にjQueryなどを用いたAjax通信などを行う際にこれに直面することが多い。

Google Chromeを使用した場合、以下のようなエラーメッセージが出る。

XMLHttpRequest cannot load http://xxx/xxx. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

オリジンサーバから最初にHTMLなどを取得した後、クロスドメインのサーバへアクセスした際、クロスドメインサーバからのHTTPレスポンスヘッダによってクロスドメインでアクセス出来るか否かの情報をクライアント(ブラウザなど)へ返却する。

CORSの通信概要

クライアント(ブラウザなど)がCORSに従ってサーバへアクセスする場合、以下の2パターンでCORSの情報をクロスドメインのサーバから取得する。

パターン1:クロスドメインのサーバに本リクエストを送る

  • 後述のpreflightリクエストのように事前に許可を求めるのではなく、いきなり本リクエストを送る
  • ただし、HTTPレスポンスヘッダにCORS情報が付与されて返却される

以下の順でアクセスする。

(1) クライアントは以下のHTTPリクエストヘッダを付与してクロスドメインのサーバへ本リクエストを送る

(2) クロスドメインのサーバは以下のHTTPレスポンスヘッダで許可する情報を返却する

  • Access-Control-Allow-Origin」・・・許可するオリジンサーバのドメイン
  • Access-Control-Expose-Headers」・・・使用を許可するHTTPリクエストヘッダ
  • Access-Control-Allow-Credentials」・・・Cookieの利用を許可するか否か
    • 例「Access-Control-Allow-Credentials: true」

パターン2:クロスドメインアクセスが可能か、クロスドメインのサーバに聞いてから本リクエストを送る

  • このリクエストを「preflightリクエスト」という
  • HTTPメソッドOPTIONSで問合せ、HTTPレスポンスヘッダでCORSの情報を得る
  • preflightリクエストを送るか否かはクライアント(ブラウザなど)の実装に依存する

以下の順でアクセスする。

(1) クライアントはOPTIONSメソッドで以下のHTTPリクエストヘッダを付与してpreflightリクエストを送付する

  • Access-Control-Request-Method」・・・preflightリクエストの後に実際に使用されるHTTPメソッド
    • 例「Access-Control-Request-Method: POST」
  • Origin」・・・オリジンサーバのドメインがセットされてる
  • Access-Control-Request-Headers」・・・preflightリクエストの後に実際に使用されるHTTPリクエストヘッダ
    • 例「Access-Control-Request-Headers: accept, origin, content-type」

(2) クロスドメインのサーバは以下のHTTPレスポンスヘッダで許可する情報を返却する

  • Access-Control-Allow-Origin」・・・許可するオリジンサーバのドメイン
  • Access-Control-Allow-Methods」・・・preflight後のHTTPリクエストで利用を許可するHTTPメソッド
    • 例「Access-Control-Allow-Methods: GET,POST,OPTIONS」
  • Access-Control-Allow-Headers」・・・preflight後のHTTPリクエストで利用を許可するHTTPリクエストヘッダ
    • 例「Access-Control-Allow-Headers: Content-Type」
  • Access-Control-Max-Age」・・・preflight後の指定した時間preflightリクエストで得た許可をキャッシュする時間
    • 例「Access-Control-Max-Age: 10」

API Gatewayでの設定

AWSAPI GatewayでもCORSの設定が可能。
Management ConsoleからAPI Gatewayを選択し、下記の画面まで進む

f:id:tanakakns:20160202142804p:plain

上記の「Enable CORS」をクリックする。

f:id:tanakakns:20160202142820p:plain

上記のように設定できるので、好きなCORS許可情報を入力するとOPTIONSメソッドが作成される。
つまりAPI Gatewayはpreflightリクエストのパターンということになる。

参考

まとめてくれてる人いたから貼っとく。

qiita.com