CORS(Cross-Origin Resource Sharing)とは、ウェブブラウザのセキュリティ機能の一つである同一オリジンポリシーの制限を緩和し、異なるオリジン間でのリソース共有を可能にする仕組みである。
具体的には、あるオリジン(ドメイン、プロトコル、ポートの組み合わせ)で動作するウェブページが、異なるオリジンにあるサーバーに対して特定のリクエストを送信し、レスポンスを受け取れるようにする。
CORSの仕組み
CORSの仕組みは、ブラウザとサーバー間で追加のHTTPヘッダーをやり取りすることで実現される。このヘッダーのやり取りによって、異なるオリジンからのリクエストを許可するかどうかを制御するのだ。
リクエストの種類とCORSの動作
CORSは、主に2つのリクエストタイプによって動作する。
-
単純リクエスト
- GET、HEAD、POSTメソッドを使用するリクエスト
- Content-Typeヘッダーがapplication/x-www-form-urlencoded、multipart/form-data、text/plainのいずれかに設定されているリクエスト
- カスタムヘッダーを含まないリクエスト
これらの条件を満たすリクエストは、ブラウザから
Origin
ヘッダーを追加してサーバーに送信される。サーバーは、Access-Control-Allow-Origin
ヘッダーで許可するオリジンを指定してレスポンスを返す。ブラウザはこのヘッダーをチェックし、許可されたオリジンからのレスポンスのみを受け入れる。 -
プリフライトリクエストを必要とするリクエスト
- PUT、DELETEなど、単純リクエスト以外のメソッドを使用するリクエスト
- カスタムヘッダーを含むリクエスト
- Content-Typeヘッダーが上記以外の値に設定されているリクエスト
これらの条件を満たすリクエストは、ブラウザからまず
OPTIONS
メソッドを使用してプリフライトリクエストが送信される。このリクエストには、Origin
、Access-Control-Request-Method
、Access-Control-Request-Headers
などのヘッダーが含まれる。サーバーは、これらのヘッダーをチェックし、リクエストを許可する場合は、Access-Control-Allow-Origin
、Access-Control-Allow-Methods
、Access-Control-Allow-Headers
などのヘッダーで許可するオリジン、メソッド、ヘッダーを指定してレスポンスを返す。ブラウザはこのレスポンスをチェックし、許可された場合にのみ、実際のリクエストを送信する。
プリフライトリクエストの役割
プリフライトリクエストは、複雑なリクエストを送信する前に、サーバーがそのリクエストを受け入れるかどうかを確認するための仕組みである。これにより、実際にリクエストを送信する前に、CORSエラーが発生するかどうかを事前に把握できる。また、プリフライトリクエストは、キャッシュされるため、同じオリジン、メソッド、ヘッダーを持つリクエストを複数回送信する場合でも、プリフライトリクエストは一度だけ送信される。
CORSのセキュリティ
CORSは、適切に設定されないと、クロスサイトリクエストフォージェリ(CSRF)などのセキュリティ脆弱性を引き起こす可能性がある。Access-Control-Allow-Origin
ヘッダーでワイルドカード(*)を使用することは、特に危険であるため、避けるべきである。代わりに、許可するオリジンを明示的に指定する必要がある。また、Access-Control-Allow-Credentials
ヘッダーをtrueに設定する場合は、Access-Control-Allow-Origin
ヘッダーでワイルドカードを使用できないことに注意が必要である。
CORSの設定
CORSの設定は、サーバー側で行う必要がある。設定方法は、使用するサーバーソフトウェアやフレームワークによって異なるが、基本的な考え方は共通している。
基本的なCORSヘッダー
CORSの設定には、主に以下のHTTPヘッダーが使用される。
Access-Control-Allow-Origin
:許可するオリジンを指定する。ワイルドカード(*)を使用することも可能だが、セキュリティ上のリスクがあるため、可能な限り具体的なオリジンを指定することが推奨される。Access-Control-Allow-Methods
:許可するHTTPメソッド(GET、POST、PUT、DELETEなど)を指定する。Access-Control-Allow-Headers
:許可するHTTPヘッダーを指定する。Access-Control-Allow-Credentials
:Cookieなどの認証情報を含めるかどうかを指定する。trueに設定する場合は、Access-Control-Allow-Origin
ヘッダーでワイルドカードを使用できない。Access-Control-Max-Age
:プリフライトリクエストの結果をキャッシュする時間を秒単位で指定する。
サーバー側での設定例
以下に、一般的なサーバーソフトウェアやフレームワークでのCORS設定例を示す。
-
Apache
.htaccess
ファイルに以下の設定を追加する。Header set Access-Control-Allow-Origin "*" Header set Access-Control-Allow-Methods "GET, POST, OPTIONS" Header set Access-Control-Allow-Headers "Content-Type"
-
Nginx
サーバーブロック内に以下の設定を追加する。
location / { add_header Access-Control-Allow-Origin "*"; add_header Access-Control-Allow-Methods "GET, POST, OPTIONS"; add_header Access-Control-Allow-Headers "Content-Type"; }
-
Node.js (Express)
cors
ミドルウェアを使用する。const express = require('express'); const cors = require('cors'); const app = express(); app.use(cors()); // ...
注意点
まとめ
CORSは、現代のウェブアプリケーション開発において不可欠な仕組みである。CORSでは、ブラウザとサーバー間でのHTTPヘッダーのやり取りによって実現される。単純リクエストとプリフライトリクエストを必要とするリクエストの2種類があり、それぞれ異なる方法でCORSの制御が行われる。プリフライトリクエストは、複雑なリクエストを送信する前に、サーバーがそのリクエストを受け入れるかどうかを確認するための重要な仕組みである。