>_devtools-hub
CORSHTTPセキュリティ

CORSの仕組みと設定 — プリフライトリクエストとAccess-Controlヘッダーを理解する

CORSエラーの原因・プリフライトリクエストの仕組み・サーバー側の正しい設定方法・よくある誤設定を解説します。「CORSエラーが出て困った」という経験を持つ開発者向けの実践ガイドです。

「ローカル環境でAPIを叩いたらCORSエラーになった」「フロントエンドとバックエンドのドメインが違うとエラーが出る」という経験は多くのフロントエンド開発者が持っています。CORSはセキュリティ上重要な仕組みですが、設定が複雑でエラーの原因がわかりにくいことも事実です。この記事では、CORSエラーの発生原因から、サーバー側の正しい設定方法、そして「とりあえず `*` にした」では解決しない問題まで、実務的な観点で解説します。

同一オリジンポリシーとCORSの関係

ブラウザには「同一オリジンポリシー(Same-Origin Policy)」というセキュリティ機能があり、スクリプトは自分と同じオリジン(スキーム+ホスト+ポートの組み合わせ)のリソースにしかアクセスできません。`https://app.example.com` のJavaScriptから `https://api.example.com` にfetchすると、ホストが異なるためブロックされます。CORS(Cross-Origin Resource Sharing)は、サーバーが「このオリジンからのアクセスは許可する」とブラウザに通知するための仕組みです。CORSはあくまでブラウザの制限であり、curlやPostmanなどのクライアントツールはCORSの影響を受けません。「curlでは動くのにブラウザで動かない」という状況はCORSが原因であることが多いです。

プリフライトリクエストとは何か

CORSの「プリフライトリクエスト」は、実際のリクエストを送る前にブラウザが自動的に送信するOPTIONSリクエストです。非シンプルリクエスト(`PUT`・`DELETE`・`PATCH` メソッド、カスタムヘッダー付き、Content-Typeが `application/json` のPOSTなど)はプリフライトが発生します。ブラウザは `OPTIONS /api/users` と `Access-Control-Request-Method: POST` などを含むリクエストを先に送り、サーバーが `Access-Control-Allow-Origin` と `Access-Control-Allow-Methods` を含むレスポンスを返せば本リクエストを送信します。REST APIを実装する際、OPTIONSメソッドへのハンドリングを忘れるとプリフライトが失敗してCORSエラーになります。これが「GETは動くのにPOSTで失敗する」という現象の典型的な原因です。

正しいAccess-Controlヘッダーの設定

`Access-Control-Allow-Origin` は許可するオリジンを指定します。`*`(ワイルドカード)は全オリジンを許可しますが、Cookieや認証ヘッダーを含むリクエスト(`credentials: "include"`)では `*` が使えず、具体的なオリジンを指定する必要があります。`Access-Control-Allow-Methods` は許可するHTTPメソッドをカンマ区切りで指定します。`Access-Control-Allow-Headers` はリクエストで使えるカスタムヘッダー(`Authorization`・`Content-Type` など)を指定します。`Access-Control-Max-Age` はプリフライトのキャッシュ時間(秒)で、設定することでプリフライトの発生頻度を減らせます。`Access-Control-Allow-Credentials: true` はCookieや認証情報の送信を許可します。この場合 `Allow-Origin` に `*` は指定できず、具体的なオリジンが必要です。

よくある誤設定と「CORSエラーを安易に回避する」危険性

`Access-Control-Allow-Origin: *` と `Access-Control-Allow-Credentials: true` を同時に設定しても無効で、ブラウザはエラーにします。これはCSRF(クロスサイトリクエストフォージェリ)への対策として意図的な設計です。開発環境で「とりあえずCORSを全許可」にしてそのまま本番に出てしまうことは、CSRF脆弱性につながります。正しい対応は「フロントエンドのオリジンのみを明示的に許可する」ことです。Next.jsなどのBFF(Backend for Frontend)を挟む構成では、フロントエンドとAPIが同一オリジンになるためCORS設定が不要になり、より安全です。HTTP Headers Referenceで各Access-Controlヘッダーの詳細仕様を確認できます。

まとめ

CORSは「セキュリティ上の制限」であり、バグではありません。正しい理解は「ブラウザが同一オリジンポリシーでアクセスをブロックしているのを、サーバー側のヘッダーで許可する」というものです。プリフライトリクエストへの対応・CredentialsとAllow-Originの組み合わせルール・本番での最小権限設定という3点を押さえることで、安全かつ正しいCORS設定が実装できます。

このツールで試す

cURL to Code

cURL コマンドを fetch / axios / Python requests / HTTPie に変換

開発者向けAPIWeb開発

使ってみる →

BOOTH

HTTP Headers Reference

主要 HTTP ヘッダーの用途・構文・使用例をまとめたリファレンス

Web開発ネットワーク

使ってみる →

BOOTH

HTTP Request Builder

GUIでHTTPリクエストを組み立て curl / fetch / axios コードを即生成

HTTPAPI開発ツールWeb開発

使ってみる →

BOOTH