CORS
CORSとは
CORS(Cross-Origin Resource Sharing、オリジン間リソース共有)は、あるサイトのJavaScriptが別のオリジンへリクエストすることを、ブラウザが条件付きで許可する仕組みです。
前提にあるのが同一オリジンポリシーという、ブラウザの基本的な安全装置です。オリジンとは「スキーム(http/https)+ホスト名+ポート番号」の組み合わせで、1つでも違えば別オリジンとみなされます。
| URL | https://example.com/app から見て |
|---|---|
https://example.com/api | 同一オリジン(パスの違いは無関係) |
http://example.com/api | 別オリジン(スキームが違う) |
https://api.example.com/ | 別オリジン(ホスト名が違う) |
https://example.com:8080/ | 別オリジン(ポートが違う) |
同一オリジンポリシーがないと、悪意あるサイトを開いただけで、そのJavaScriptがログイン済みの別サイトのデータを読み取れてしまいます。CORS は、この原則を保ったまま「サーバー側が許可した相手にだけ例外を認める」ための取り決めです。
どうやって許可するか
許可の判断をするのはブラウザですが、許可を出すのはサーバーです。サーバーが [[HTTP]] レスポンスヘッダーで意思表示します。
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Headers: Content-Type, Authorization
ブラウザはリクエストに Origin ヘッダーを付けて送り、返ってきた Access-Control-Allow-Origin に自分のオリジンが含まれていなければ、レスポンスをJavaScriptに渡さずエラーにします。
プリフライトリクエスト
PUT / DELETE などのメソッド、Content-Type: application/json、独自ヘッダー(認証トークンなど)を使う場合、本番のリクエストの前に確認用のリクエストが自動で飛びます。これがプリフライトです。
ブラウザはまず OPTIONS メソッドで「このメソッドとヘッダーを使ってよいか」を尋ね、サーバーが許可を返して初めて本番のリクエストを送ります。[[REST API]] を JSON でやりとりする構成では、ほぼ必ずプリフライトが発生します。
よくある誤解
- CORSはサーバーを守る仕組みではない — 守っているのは利用者のブラウザです。curl やサーバー同士の通信には CORS は関係なく、そのまま届きます。API 自体の保護は認証・認可で行います
- エラーが出るのはブラウザ側だが、直すのはサーバー側 — フロントエンドのコードをいじって回避するものではありません。[[fetchと非同期通信]] から見ると通信そのものが失敗したように見え、ステータスコードすら読めないため、原因の切り分けは開発者ツールの Network タブで行います
Access-Control-Allow-Origin: *は手軽だが危険 — 誰でも読める公開データ以外では使いません。許可範囲を広げすぎることは [[Webセキュリティ]] 上のリスクに直結します- Cookieを伴う通信は別扱い — [[セッション管理]] の Cookie を別オリジンのAPIに送るには
credentials: 'include'とAccess-Control-Allow-Credentials: trueが必要で、許可オリジンにワイルドカードは使えません
初学者向けポイント
- 開発中に頻出するエラーです。切り分けは「サーバーが期待するオリジンを許可しているか」から始めます
- 開発用サーバーのプロキシ機能で同一オリジンに見せかけて回避する手もありますが、本番構成では正しくヘッダーを設定します
- CORS を緩めても [[XSS(クロスサイトスクリプティング)]] のような別の攻撃への対策の代わりにはなりません
関連技術とのつながり
- [[HTTP]] — CORS はレスポンスヘッダーによる取り決め
- [[REST API]] — JSON APIの呼び出しでプリフライトが発生する
- [[セッション管理]] — Cookie を伴う通信は追加設定が必要
- [[Webセキュリティ]] — 許可範囲を広げすぎるとリスクになる
- [[XSS(クロスサイトスクリプティング)]] — ブラウザ上で起きる別種の脅威
- [[セキュリティヘッダー(CSP・HSTS)]] — CORSは既定の禁止を緩め、こちらは既定の許可を絞る
Q: CORSの許可を最終的に判断・実行しているのはどれ?
- [x] ブラウザ(サーバーが返したヘッダーをもとに判断する)
- [ ] DNSサーバー
- [ ] OSのファイアウォール
解説: 許可を出すのはサーバーのヘッダーですが、それをもとに遮断を実行するのはブラウザです。
Q: 別オリジンとみなされる組み合わせはどれ?
- [ ] パスだけが違うURL
- [x] ポート番号が違うURL
- [ ] 参照した時刻だけが違うURL
解説: オリジンはスキーム・ホスト名・ポートの組み合わせで、パスは含まれません。
Q: プリフライトリクエストで使われるHTTPメソッドはどれ?
- [ ] GET
- [x] OPTIONS
- [ ] PATCH
解説: ブラウザは本番リクエストの前に OPTIONS で許可されるメソッドやヘッダーを確認します。