複数の特定オリジンを許可する
複数のフロントエンドドメインがアクセスする必要がある場合のCORS処理。許可リストからAllow-Originを動的に設定するサーバーサイドパターンを学びます。
Basic CORS
詳細な説明
許可リストからの動的オリジン
Access-Control-Allow-Originヘッダーは1つの値(または*)のみ受け付けます。複数のオリジンをカンマ区切りにすることはできません。https://app.example.comとhttps://admin.example.comを許可する必要がある場合、サーバーは受信したOriginヘッダーを許可リストと照合し、一致した場合にエコーバックする必要があります。
サーバーロジック(擬似コード)
allowed = ["https://app.example.com", "https://admin.example.com"]
if request.headers["Origin"] in allowed:
response.headers["Access-Control-Allow-Origin"] = request.headers["Origin"]
response.headers["Vary"] = "Origin"
Nginx実装
map $http_origin $cors_origin {
default "";
"https://app.example.com" "$http_origin";
"https://admin.example.com" "$http_origin";
}
if ($cors_origin != "") {
add_header Access-Control-Allow-Origin $cors_origin always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
add_header Access-Control-Allow-Credentials "true" always;
add_header Vary Origin always;
}
Express.js実装
const allowedOrigins = [
"https://app.example.com",
"https://admin.example.com",
];
app.use(cors({
origin: (origin, callback) => {
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error("Not allowed by CORS"));
}
},
credentials: true,
}));
なぜVary: Originが重要か
レスポンスがリクエスト元のオリジンによって変わるため、キャッシュはOriginヘッダーをキーとして使用する必要があります。Vary: Originがないと、CDNがapp.example.com向けのレスポンスをキャッシュしてadmin.example.comに配信する可能性があり、ブラウザのオリジンチェックに失敗します。
ユースケース
顧客向け(app.example.com)と社内スタッフ向け(admin.example.com)に別々のフロントエンドアプリを持つ企業で、両方が同じREST APIを消費しています。各オリジンを明示的にホワイトリストに登録する必要があります。