Access-Control-Allow-Origin の * が credentials 付きで失敗する理由
フロントエンドが cookies や認証付きのリクエストを送るときに、Allow-Origin を `*` にしてしまう代表的な CORS ミスをブラウザ目線で整理します。
CORS で特に混乱しやすいのが、見た目は十分に許可しているように見えるのにブラウザでは失敗するケースです。API が Access-Control-Allow-Origin: * を返しており、Postman では成功するため、バックエンドは問題ないように見えます。ところがフロントエンドが cookies や認証付きの状態を送ると、ブラウザはそのレスポンスを JavaScript に渡しません。
ここで重要なのは、ワイルドカード CORS を「常に開放的」と考えないことです。匿名の公開読み取りでは * が成立することがありますが、credentials を伴うブラウザ通信ではより明示的な契約が必要になります。ブラウザは * を十分な許可とは見なしません。
まず API バグではなくブラウザ境界の問題だと捉える
この問題で時間を失いやすい理由は、ブラウザの外では成功してしまうことです。Postman や curl、サーバーサイドのスクリプトは、ブラウザと同じ CORS 制約を強制しません。そのため API 自体は到達可能でも、ブラウザはフロントエンドへレスポンスを渡さないことがあります。
最初に考えるべきなのは「API がデータを返したか」ではなく、「この origin と credentials 条件でブラウザが安全だと判断したか」です。この境界に意識を置くと、ワイルドカードは“十分に開いている設定”ではなく、“このケースには不十分な設定”だと見えてきます。
このセクションで使うツール
credentials があると wildcard Allow-Origin が破綻する理由を理解する
credentials 付きの CORS リクエストでは、cookies や認証状態などの敏感なコンテキストが運ばれる可能性があります。そのためブラウザは Access-Control-Allow-Origin: * と credentials の組み合わせを安全とは見なしません。サーバーには、どの origin を許可するのかを具体的に示すことが求められます。
つまり、サーバーがリクエストを拒否しているわけではなく、ブラウザがワイルドカード応答を信用していないのです。実務上の修正は、実際のフロントエンド origin を明示的に返し、credentials の方針をその origin に合わせることがほとんどです。
このセクションで使うツール
1 回の失敗として見ず、preflight と本体レスポンスに分けて調べる
実践的な進め方は、ブラウザの判断を 2 段階に分けることです。まず method や custom headers によって preflight が発生するかを確認します。その後、credentials 条件を含めた本体レスポンスのヘッダーが本当に整合しているかを確認します。多くのチームはアプリのルートだけを見て、ブラウザがその前段階でポリシーを拒否していることを見落とします。
次の順で見ると速くなります。
- リクエストが simple か preflight 付きかを確認する。
- method と custom headers が preflight レスポンスで許可されているか照合する。
- 本体レスポンスの
Access-Control-Allow-Originが credentials 条件に対して十分に明示的か確認する。 - 本番では proxy、CDN、auth 層がヘッダーを書き換えていないかを確認する。
この順序なら、推測でヘッダーを変えてデプロイを繰り返すよりずっと効率的です。
このセクションで使うツール
CORS Header Checker
Check whether a browser request will pass CORS based on the request method, custom headers, credentials mode, and the response headers your API returns.
HTTP Status Code Explorer
Search common HTTP status codes, compare confusing client and server failures, and keep a sharper API debugging checklist in the browser.
JWT Decoder
Decode and inspect JWT tokens instantly to view headers, payloads, and expiration status locally in your browser.