はじめに
この記事では、Web開発を始めたばかりの方が必ず一度は遭遇する「CORS」について、その概念と仕組みを分かりやすく解説します。
この記事で学べること
- CORSが必要とされる理由
- CORSの基本的な仕組み
- よくあるエラーとその対処方法
対象読者
- Web開発を学び始めた方
- 「CORSエラー」に遭遇して困っている方
- APIを使った開発に取り組んでいる方
CORSが必要な理由
CORSを理解するには、まず「同一オリジンポリシー」というWebブラウザのセキュリティ機能を知る必要があります。
Webブラウザのセキュリティ「同一オリジンポリシー」
Webブラウザには、悪意のあるサイトから私たちを守るための仕組みが備わっています。それが同一オリジンポリシーです。
この仕組みは、あるWebページから別のオリジン(異なるサイト)のリソースに対して、JavaScriptでアクセスすることを原則として禁止しています。
オリジン(Origin)とは何か
オリジンは以下の3つの要素の組み合わせで決まります。
-
スキーム(プロトコル):
httpまたはhttps -
ホスト(ドメイン):
example.com -
ポート番号:
80、443、3000など
これらの3つがすべて一致している場合、同一オリジンとみなされます。
同一オリジンの例
-
https://example.com/page1とhttps://example.com/page2→ 同一オリジン -
https://example.com:443/apiとhttps://example.com/data→ 同一オリジン
異なるオリジンの例
-
https://example.comとhttp://example.com→ スキームが違う -
https://example.comとhttps://api.example.com→ ホストが違う -
https://example.com:443とhttps://example.com:3000→ ポート番号が違う
なぜ他のサイトへのアクセスを制限するのか
同一オリジンポリシーがないと、悪意のあるサイトが勝手に他のサイトのデータを取得できてしまいます。
たとえば、こんな攻撃が可能になってしまいます。
同一オリジンポリシーは、このような攻撃からユーザーを守る重要な仕組みなのですね。
CORSとは何か
CORSの正式名称と役割
CORSは「Cross-Origin Resource Sharing」の略で、日本語では「オリジン間リソース共有」と呼ばれます。
同一オリジンポリシーは安全性のために重要ですが、すべての異なるオリジンへのアクセスを禁止してしまうと、正当な理由でのデータ取得もできなくなってしまいます。
CORSは、安全性を保ちながら、必要な場合に限って異なるオリジンへのアクセスを許可する仕組みです。
CORSが解決する問題
現代のWeb開発では、フロントエンドとバックエンドのAPIが異なるドメインで動作することがよくあります。
- フロントエンド:
https://myapp.com - API:
https://api.myapp.com
この場合、同一オリジンポリシーによってブラウザがAPIへのアクセスをブロックしてしまいます。CORSを使うことで、サーバー側が「このオリジンからのアクセスは許可します」と明示的に宣言できるのです。
実際の利用シーン
CORSが使われる代表的な場面を見てみましょう。
-
外部APIの利用
- 天気情報APIやマップAPIなど、外部サービスのデータを取得する
-
マイクロサービス構成
- フロントエンドとバックエンドが別々のサーバーで動作する
-
CDNからのリソース読み込み
- 画像やフォントなどを外部のCDNから読み込む
CORSの仕組み
CORSには主に2つのパターンがあります。
シンプルリクエストの流れ
特定の条件を満たすリクエストは「シンプルリクエスト」として扱われ、1回のやり取りでアクセスが完了します。
シンプルリクエストの条件は以下の通りです。
- メソッドが
GET、POST、HEADのいずれか - 特定のヘッダーのみを使用している
-
Content-Typeがapplication/x-www-form-urlencoded、multipart/form-data、text/plainのいずれか
プリフライトリクエストの流れ
シンプルリクエストの条件を満たさない場合、ブラウザは本リクエストの前に「プリフライトリクエスト」を送信します。
プリフライトリクエストでは、以下の情報を確認します。
- どのHTTPメソッドが許可されているか
- どのヘッダーが許可されているか
- どのオリジンが許可されているか
レスポンスヘッダーの役割
サーバーは以下のようなヘッダーを使って、アクセス許可を制御します。
Access-Control-Allow-Origin
どのオリジンからのアクセスを許可するかを指定します。
Access-Control-Allow-Origin: https://myapp.com
すべてのオリジンを許可する場合(セキュリティリスクがあるため注意が必要です)。
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods
許可するHTTPメソッドを指定します。
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers
許可するリクエストヘッダーを指定します。
Access-Control-Allow-Headers: Content-Type, Authorization
よくあるCORSエラーとその対処法
エラーメッセージの見方
CORSエラーが発生すると、ブラウザのコンソールに以下のようなメッセージが表示されます。
Access to fetch at 'https://api.example.com/data' from origin 'https://myapp.com'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present
on the requested resource.
このメッセージは「APIサーバーが適切なCORSヘッダーを返していない」ことを示しています。
基本的な解決方法
CORSエラーの解決方法は、主にサーバー側での対応が必要です。
Node.js + Expressの例
corsパッケージを使用する方法です。
const express = require('express');
const cors = require('cors');
const app = express();
// すべてのオリジンを許可
app.use(cors());
// 特定のオリジンのみ許可
app.use(cors({
origin: 'https://myapp.com'
}));
手動でヘッダーを設定する例
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', 'https://myapp.com');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
next();
});
開発環境での一時的な対処
開発中のみ、プロキシを使ってCORSを回避することもできます。たとえば、Viteを使用している場合は設定ファイルで以下のように記述します。
// vite.config.js
export default {
server: {
proxy: {
'/api': {
target: 'https://api.example.com',
changeOrigin: true
}
}
}
}
ただし、これはあくまで開発環境での一時的な対処法です。本番環境ではサーバー側で適切なCORS設定を行う必要があります。
まとめ
CORSについて、重要なポイントを整理しましょう。
- 同一オリジンポリシーはWebブラウザのセキュリティ機能で、異なるオリジンへのアクセスを制限している
- オリジンはスキーム、ホスト、ポート番号の組み合わせで決まる
- CORSは安全性を保ちながら、必要な場合に異なるオリジンへのアクセスを許可する仕組み
- CORSの設定は基本的にサーバー側で行う必要がある
- 適切なレスポンスヘッダーを設定することで、CORSエラーを解決できる
CORSは最初は難しく感じるかもしれませんが、Webのセキュリティを守るための重要な仕組みです。この記事が、CORSへの理解を深める一助となれば幸いです。