CORS(Cross-Origin Resource Sharing)とは?仕組みと設定方法を初心者向けに徹底解説

 

はじめに

Webアプリケーション開発において、「CORSエラー」に遭遇した経験はありませんか?突然表示される「Access to fetch at ‘https://api.example.com’ from origin ‘http://localhost:3000’ has been blocked by CORS policy」といったエラーメッセージに困惑した開発者は多いはずです。

CORS(Cross-Origin Resource Sharing)は、現代のWeb開発において避けて通れない重要な概念です。この記事では、CORSの基本概念から具体的な設定方法まで、初心者にもわかりやすく解説します。

CORSとは

基本的な定義

**CORS(Cross-Origin Resource Sharing / オリジン間リソース共有)**とは、異なるオリジン(ドメイン、プロトコル、ポート)間でのWebリソースへのアクセスを制御するセキュリティ機能です。ブラウザに標準搭載されており、悪意のあるサイトからの不正なリクエストを防ぐ役割を果たしています。

オリジンとは

オリジンは以下の3つの要素で構成されます:

  • プロトコル(http, https)
  • ドメイン(example.com, api.example.com)
  • ポート番号(80, 443, 3000など)

これらのうち**いずれか一つでも異なる場合は「異なるオリジン」**として扱われます。

同一オリジンの例

  • https://example.com/page1https://example.com/page2

異なるオリジンの例

  • https://example.comhttp://example.com(プロトコルが異なる)
  • https://example.comhttps://api.example.com(サブドメインが異なる)
  • https://example.comhttps://example.com:8080(ポートが異なる)

なぜCORSが必要なのか

同一オリジンポリシーの制約

ブラウザには**同一オリジンポリシー(Same-Origin Policy)**というセキュリティ機能が組み込まれています。これは、あるオリジンで読み込まれたスクリプトが、異なるオリジンのリソースにアクセスすることを原則として禁止する仕組みです。

セキュリティ上の意義

同一オリジンポリシーがない場合、以下のような攻撃が可能になってしまいます:

クロスサイトリクエストフォージェリ(CSRF) 悪意のあるサイトが、ユーザーの認証情報を利用して他のサイトに不正なリクエストを送信する攻撃です。

機密情報の窃取 悪意のあるサイトが、ユーザーがログインしている他のサイトから個人情報を盗み取る攻撃です。

現代Web開発での課題

一方で、現代のWebアプリケーションでは以下のような正当な理由で異なるオリジン間の通信が必要です:

  • API サーバーとフロントエンドの分離
  • CDN からの静的リソース取得
  • 外部サービス との連携
  • マイクロサービス アーキテクチャでのサービス間通信

CORSは、セキュリティを保ちながら必要な異なるオリジン間通信を安全に許可する仕組みを提供します。

CORSの動作メカニズム

シンプルリクエスト

以下の条件をすべて満たすリクエストはシンプルリクエストとして扱われます:

許可されるHTTPメソッド

  • GET
  • HEAD
  • POST

許可されるヘッダー

  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type(特定の値のみ)

許可されるContent-Type

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

シンプルリクエストの場合、ブラウザはプリフライトリクエストを送信せず、直接本来のリクエストを送信します。サーバーは適切なCORSヘッダーを返す必要があります。

プリフライトリクエスト

シンプルリクエストの条件を満たさない場合、ブラウザは本来のリクエストの前にプリフライトリクエストを送信します。

プリフライトリクエストの流れ

  1. OPTIONS リクエストの送信 ブラウザが自動的に OPTIONS メソッドでプリフライトリクエストを送信

  2. サーバーの許可確認 サーバーが適切な CORS ヘッダーで応答

  3. 本来のリクエスト送信 プリフライトが成功した場合のみ、本来のリクエストを送信

  4. レスポンスの処理 サーバーからの最終的なレスポンスを JavaScript で処理

CORSヘッダーの詳細

Access-Control-Allow-Origin リクエストを許可するオリジンを指定します。

  • *:すべてのオリジンを許可(認証情報との併用不可)
  • 特定のオリジン:https://example.com

Access-Control-Allow-Methods 許可するHTTPメソッドを指定します。 GET, POST, PUT, DELETE, OPTIONS

Access-Control-Allow-Headers リクエストで送信を許可するヘッダーを指定します。 Content-Type, Authorization, X-Requested-With

Access-Control-Allow-Credentials 認証情報(Cookie、Authorization ヘッダー)の送信を許可するかを指定します。 true または false

Access-Control-Max-Age プリフライトリクエストの結果をキャッシュする秒数を指定します。 86400(24時間)

よくあるCORSエラーとその対処法

エラー1: 「No ‘Access-Control-Allow-Origin’ header」

原因 サーバーがCORSヘッダーを設定していない、または間違ったオリジンを指定している。

対処法 サーバー側で適切な Access-Control-Allow-Origin ヘッダーを設定します。

エラー2: 「Method not allowed」

原因 使用しているHTTPメソッドがサーバー側で許可されていない。

対処法 Access-Control-Allow-Methods ヘッダーに必要なメソッドを追加します。

エラー3: 「Request header field not allowed」

原因 カスタムヘッダーがサーバー側で許可されていない。

対処法 Access-Control-Allow-Headers ヘッダーに必要なヘッダー名を追加します。

エラー4: 「Credentials flag is ‘true’, but ‘Access-Control-Allow-Origin’ is ‘*’」

原因 認証情報を送信する際に、オリジンにワイルドカード(*)を使用している。

対処法 認証情報を使用する場合は、オリジンを具体的に指定する必要があります。

サーバー側でのCORS設定

Express.js(Node.js)での設定

Express.js では cors ミドルウェアを使用して簡単にCORSを設定できます。

基本的な設定 すべてのオリジンを許可する最もシンプルな設定です。

特定のオリジンのみ許可 セキュリティを考慮し、特定のオリジンのみにアクセスを制限します。

詳細な設定 メソッド、ヘッダー、認証情報などを細かく制御できます。

Spring Boot(Java)での設定

Spring Boot では @CrossOrigin アノテーションやグローバル設定でCORSを制御できます。

コントローラーレベルでの設定 特定のコントローラーやメソッドにのみCORSを適用します。

グローバル設定 アプリケーション全体でCORSポリシーを統一します。

ASP.NET Core(C#)での設定

ASP.NET Core では Startup.cs でCORSポリシーを設定します。

基本的なポリシー設定 CORSポリシーを定義し、ミドルウェアとして有効化します。

Django(Python)での設定

Django では django-cors-headers パッケージを使用してCORSを設定します。

インストールと基本設定 必要なパッケージをインストールし、設定ファイルを更新します。

フロントエンド側での対応

fetch APIでのリクエスト

認証情報を含むリクエスト Cookie や Authorization ヘッダーを送信する場合の設定方法です。

カスタムヘッダーの送信 API キーなどのカスタムヘッダーを含むリクエストの例です。

axios での設定

axios を使用している場合の CORS 対応方法です。

グローバル設定 すべてのリクエストに適用される設定を行います。

インスタンス別設定 特定の API エンドポイント用のインスタンスを作成します。

開発環境でのCORS問題

ローカル開発でのよくある問題

フロントエンド: http://localhost:3000 バックエンド API: http://localhost:8080

この構成では、ポート番号が異なるため異なるオリジンとして扱われ、CORSエラーが発生します。

開発環境での対処法

1. 開発サーバーのプロキシ設定 Create React App、Vue CLI、Angular CLI などでは、プロキシ設定により CORS 問題を回避できます。

2. ブラウザのCORS無効化 開発時限定でブラウザの CORS チェックを無効化する方法もありますが、本番環境では使用できません。

3. 開発用 CORS 設定 開発環境でのみ緩い CORS 設定を使用し、本番環境では厳格な設定を適用します。

セキュリティのベストプラクティス

最小権限の原則

必要最小限のオリジンのみ許可 ワイルドカード(*)の使用は避け、具体的なオリジンを指定します。

必要な HTTP メソッドのみ許可 不要なメソッドは許可せず、セキュリティリスクを最小限に抑えます。

環境別の設定管理

開発環境 開発効率を重視し、比較的緩い設定を使用します。

ステージング環境 本番環境に近い厳格な設定でテストを実施します。

本番環境 最も厳格な設定を適用し、セキュリティを最優先にします。

認証情報の取り扱い

Cookie の適切な設定 SameSiteSecureHttpOnly 属性を適切に設定します。

JWT トークンの管理 Authorization ヘッダーでの JWT 送信時の CORS 設定を適切に行います。

トラブルシューティング

デバッグ手順

1. ブラウザの開発者ツールを確認 Network タブでリクエスト・レスポンスのヘッダーを詳細に確認します。

2. プリフライトリクエストの確認 OPTIONS リクエストが正しく処理されているかを確認します。

3. サーバーログの確認 サーバー側でCORSミドルウェアが正しく動作しているかを確認します。

よくある設定ミス

ヘッダー名の大文字小文字 HTTP ヘッダーは大文字小文字を区別しないため、統一して記述します。

末尾のスラッシュ オリジンの指定時に不要なスラッシュが含まれていないかを確認します。

環境変数の設定ミス 本番環境で開発用の設定が使用されていないかを確認します。

パフォーマンスへの影響と最適化

プリフライトリクエストの最適化

Access-Control-Max-Age の設定 適切なキャッシュ期間を設定し、不要なプリフライトリクエストを削減します。

シンプルリクエストの活用 可能な限りシンプルリクエストの条件を満たすようにAPI設計を調整します。

CDNとの連携

静的リソースのCORS設定 画像、CSS、JavaScript ファイルなどの静的リソースに対する適切な CORS 設定を行います。

CDN キャッシュの考慮 CDN を使用している場合の CORS ヘッダーキャッシュについて理解し、適切に設定します。

今後の技術動向

Trusted Web Activity

Progressive Web App(PWA)や Trusted Web Activity での CORS の扱いについて理解しておくことが重要です。

Service Worker との関係

Service Worker を使用したアプリケーションでの CORS の動作について把握しておく必要があります。

セキュリティヘッダーとの連携

Content Security Policy(CSP) CSP と CORS の適切な組み合わせによる多層防御を実現します。

Feature Policy / Permissions Policy 新しいセキュリティ機能との連携を考慮した設計を行います。

まとめ

CORS は現代の Web 開発において避けて通れない重要な技術です。適切な理解と設定により、セキュリティを保ちながら柔軟な Web アプリケーションを構築できます。

重要なポイント

セキュリティとのバランス

  • 必要最小限の権限のみを許可
  • 環境に応じた適切な設定の使い分け

開発効率の向上

  • 開発環境での適切なCORS設定
  • デバッグツールの効果的な活用

パフォーマンスの最適化

  • プリフライトリクエストの削減
  • 適切なキャッシュ設定

継続的な学習

  • 新しいWeb標準への対応
  • セキュリティベストプラクティスの更新

CORS エラーに遭遇した際は、慌てずに本記事で紹介した手順に従ってデバッグを行い、適切な設定を施してください。セキュリティを損なうことなく、ユーザーフレンドリーな Web アプリケーションの開発を実現しましょう。

■プロンプトだけでオリジナルアプリを開発・公開してみた!!

■AI時代の第一歩!「AI駆動開発コース」はじめました!

テックジム東京本校で先行開始。

■テックジム東京本校

「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。

<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。

<オンライン無料>ゼロから始めるPython爆速講座