CORS(Cross-Origin Resource Sharing)は、ウェブブラウザが異なるオリジン(プロトコル、ドメイン、またはポートが異なるURL)間でリソースを共有する際に利用される仕組みです。これにより、セキュリティを維持しつつ、必要な外部リソースの利用が可能になります。
特に、同一ドメイン内で異なるサブドメイン間の通信が必要となるケースが多くあります。例えば、api.example.com
から app.example.com
へのリクエストはデフォルトでは制限されますが、適切なCORS設定を行うことで安全にリソースを共有できます。
本記事では、Apacheを用いて異なるサブドメイン間でCORSを設定する方法を具体的に解説します。基本的なCORSの概念から、サブドメインごとの具体的な設定手順、デバッグ方法やトラブルシューティングまで、幅広くカバーしています。
ApacheでのCORS設定を理解し、効率的に適用することで、異なるサブドメイン間のリソース共有をスムーズに行うことが可能になります。
CORSとは何か
CORS(Cross-Origin Resource Sharing)は、ウェブアプリケーションが異なるオリジン間でリソースを安全に共有できるようにするセキュリティ機構です。
ブラウザはセキュリティ上の理由から、同一オリジンポリシー(Same-Origin Policy)に従い、異なるオリジンからのリクエストをデフォルトでブロックします。このポリシーは、悪意のあるサイトがユーザーの情報を盗み出すことを防ぐために設計されています。
しかし、近年のウェブアプリケーションでは、外部APIや異なるサブドメインからのデータ取得が必要な場面が増えています。CORSはこのようなニーズに対応し、安全に異なるオリジン間でリソースをやり取りするための方法を提供します。
具体的な例
例えば、https://app.example.com
から https://api.example.com
にリクエストを送信する場合、デフォルトではエラーが発生します。これを防ぐために、api.example.com
側で適切なCORSヘッダーを設定する必要があります。
以下はその例です:
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST
これにより、app.example.com
からのリクエストが許可されます。
なぜCORSが必要なのか
CORSは以下のような場面で重要です。
- 外部APIの利用:外部サービスのAPIを利用する際に、アクセスを許可するため。
- サブドメイン間通信:同一サイトの異なるサブドメイン間でデータを共有する際。
- シングルページアプリケーション(SPA):フロントエンドとバックエンドが異なるサーバーで動作する場合。
CORSの理解と適切な設定は、安全なウェブアプリケーションの構築に不可欠です。次のセクションでは、サブドメイン間のCORSの仕組みについてさらに詳しく解説します。
サブドメイン間のCORSの仕組み
サブドメイン間のCORSは、同一ドメイン内で異なるサブドメイン同士がリソースを共有する際に適用されます。例えば、api.example.com
と app.example.com
は異なるサブドメインであり、デフォルトではCORSの制約が適用されます。
同一サイトと同一オリジンの違い
- 同一サイト:
example.com
配下のすべてのサブドメイン(例:app.example.com
やapi.example.com
)が同一サイトと見なされます。 - 同一オリジン:プロトコル、ドメイン、ポートがすべて一致する場合を指します。
https://app.example.com
とhttps://api.example.com
は異なるオリジンです。
この違いが重要で、サブドメイン間であってもCORSが必要になります。
サブドメイン間CORSの仕組み
異なるサブドメイン間でのリソース共有を許可するには、リクエストを受けるサーバー側で適切なHTTPヘッダーを付与する必要があります。
以下は、api.example.com
が app.example.com
からのリクエストを許可する設定例です:
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type
これにより、特定のサブドメインからのアクセスが許可され、指定されたHTTPメソッドとヘッダーが利用可能になります。
ワイルドカード設定の注意点
Access-Control-Allow-Origin
でワイルドカード(*
)を使用すれば、すべてのオリジンからのアクセスを許可できますが、セキュリティリスクが高まります。
Access-Control-Allow-Origin: *
そのため、サブドメイン間では特定のドメインのみ許可する方が望ましいです。
次のセクションでは、Apacheで具体的にCORSを設定する方法について説明します。
ApacheでのCORS設定の基本
ApacheでCORSを有効にするには、適切なHTTPヘッダーをサーバーからクライアントに送信するよう設定します。これにより、異なるオリジンからのリクエストが許可されます。
基本的な設定手順
ApacheでCORSを有効にするには、httpd.conf
または .htaccess
ファイルに以下のような記述を追加します。
この設定は特定のオリジンからのリクエストのみを許可する例です。
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "https://app.example.com"
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Header set Access-Control-Allow-Headers "Content-Type"
</IfModule>
設定内容の解説
- Access-Control-Allow-Origin:許可するオリジンを指定します。特定のオリジン(例:
https://app.example.com
)を指定するのが一般的です。 - Access-Control-Allow-Methods:許可するHTTPメソッド(
GET
、POST
など)を指定します。 - Access-Control-Allow-Headers:クライアントからのリクエストで使用できるカスタムヘッダーを指定します。
すべてのオリジンを許可する場合
開発環境などでオリジンを制限しない場合は、次のようにワイルドカード(*
)を使用します。
Header set Access-Control-Allow-Origin "*"
ただし、本番環境ではセキュリティの観点から特定のオリジンを指定することを推奨します。
mod_headersモジュールの有効化
CORS設定にはmod_headers
モジュールが必要です。有効化されていない場合は、以下のコマンドで有効にします。
a2enmod headers
systemctl restart apache2
これでApacheがCORSヘッダーを適切に処理できるようになります。
次のセクションでは、特定のサブドメインごとに異なるCORS設定を行う具体例を紹介します。
サブドメイン別のCORS設定例
Apacheでは、サブドメインごとに異なるCORS設定を行うことができます。これにより、必要なサブドメインだけにアクセスを許可し、セキュリティを強化できます。
サブドメインごとの設定方法
Apacheのバーチャルホスト設定または.htaccess
ファイルを使って、特定のサブドメインに対して異なるCORSポリシーを適用できます。以下は、app.example.com
と admin.example.com
で異なるCORS設定を行う例です。
バーチャルホスト設定例
/etc/apache2/sites-available/example.com.conf
のバーチャルホスト設定ファイルに以下を追加します。
<VirtualHost *:80>
ServerName app.example.com
<Location />
Header set Access-Control-Allow-Origin "https://api.example.com"
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Header set Access-Control-Allow-Headers "Content-Type"
</Location>
</VirtualHost>
<VirtualHost *:80>
ServerName admin.example.com
<Location />
Header set Access-Control-Allow-Origin "https://internal-api.example.com"
Header set Access-Control-Allow-Methods "GET, POST"
Header set Access-Control-Allow-Headers "Authorization, Content-Type"
</Location>
</VirtualHost>
設定のポイント
ServerName
:各サブドメインごとにバーチャルホストを定義します。Header set Access-Control-Allow-Origin
:サブドメインごとにアクセスを許可するオリジンを明確に指定します。Access-Control-Allow-Headers
:必要に応じてクライアントが送信できるヘッダーを設定します。
.htaccessでの設定例
バーチャルホスト設定を編集できない場合は、各サブドメインのドキュメントルート内に.htaccess
ファイルを作成し、以下のように記述します。
app.example.com の .htaccess:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "https://api.example.com"
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Header set Access-Control-Allow-Headers "Content-Type"
</IfModule>
admin.example.com の .htaccess:
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "https://internal-api.example.com"
Header set Access-Control-Allow-Methods "GET, POST"
Header set Access-Control-Allow-Headers "Authorization, Content-Type"
</IfModule>
ワイルドカードを使用した柔軟な設定
特定のサブドメインに対して複数のオリジンを許可する場合、正規表現を使用して柔軟に設定できます。
Header set Access-Control-Allow-Origin "https://*.example.com"
この設定により、api.example.com
や admin.example.com
など、任意のサブドメインからのアクセスが許可されます。
次のセクションでは、.htaccessを使用した簡単なCORS設定について詳しく解説します。
.htaccessを使ったCORS設定
.htaccess
ファイルは、Apacheの設定をディレクトリ単位でカスタマイズするための強力なツールです。特にサーバー全体の設定にアクセスできない場合や、サブドメインごとに細かくCORSを設定したい場合に役立ちます。
.htaccessでCORSを設定するメリット
- ディレクトリ単位で設定可能:特定のサブドメインやフォルダにだけCORSを適用できる。
- 柔軟な運用:バーチャルホストの設定変更が不要で、すぐに反映される。
- 迅速なテストとデバッグ:
.htaccess
を使えば、開発環境で簡単にCORS設定を試せる。
基本的な.htaccessでのCORS設定
以下は、特定のオリジン(例:https://app.example.com
)に対してCORSを許可する.htaccess
ファイルの例です。
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "https://app.example.com"
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Header set Access-Control-Allow-Headers "Content-Type, Authorization"
</IfModule>
この設定を.htaccess
ファイルに記述し、サブドメインのドキュメントルートに配置します。
複数のサブドメインに対応する設定
サブドメインを複数許可する場合は、環境変数や正規表現を使うことで効率的に設定できます。
<IfModule mod_rewrite.c>
RewriteEngine On
SetEnvIf Origin "^https://(app|admin)\.example\.com$" AccessControlAllowOrigin=$0
</IfModule>
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "%{AccessControlAllowOrigin}e" env=AccessControlAllowOrigin
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Header set Access-Control-Allow-Headers "Content-Type, Authorization"
</IfModule>
この例では、app.example.com
とadmin.example.com
からのアクセスが許可されます。
ワイルドカードを使用する場合
ワイルドカードを使ってすべてのオリジンからのリクエストを許可する場合は、以下のように設定します。
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Header set Access-Control-Allow-Headers "Content-Type"
</IfModule>
ただし、セキュリティ上のリスクが高いため、本番環境では特定のオリジンを明示的に指定することが推奨されます。
プリフライトリクエストの処理
ブラウザは安全性を確保するため、特定のリクエスト(例:PUT
やDELETE
)の前にプリフライトリクエスト(OPTIONS)を送信します。このプリフライトリクエストを処理するには、以下の設定が必要です。
<IfModule mod_headers.c>
Header always set Access-Control-Allow-Origin "https://app.example.com"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE"
Header always set Access-Control-Allow-Headers "Authorization, Content-Type"
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
</IfModule>
この設定により、OPTIONSリクエストが200で返され、CORSポリシーが適切に適用されます。
次のセクションでは、CORS設定の確認方法とデバッグについて詳しく解説します。
設定の確認とデバッグ方法
CORS設定は意図通りに動作しないことがあるため、設定後は動作確認とデバッグが重要です。ApacheでCORSが正しく反映されているかを確認するための方法を解説します。
CORS設定の確認方法
1. ブラウザの開発者ツールで確認
- Google ChromeやFirefoxなどのブラウザには「開発者ツール」が搭載されています。
- [F12]または[Ctrl + Shift + I]で開発者ツールを起動し、[ネットワーク]タブでリクエストの詳細を確認します。
- CORSエラーが発生している場合は、「CORS policy」関連のエラーがコンソールに表示されます。
Access to fetch at 'https://api.example.com' from origin 'https://app.example.com' has been blocked by CORS policy.
- 「レスポンスヘッダー」で
Access-Control-Allow-Origin
が正しく設定されているか確認してください。
2. curl
コマンドで確認
コマンドラインでcurl
を使用して、CORSヘッダーが適用されているか確認できます。
curl -I https://api.example.com
このコマンドはレスポンスヘッダーを表示します。以下のようにAccess-Control-Allow-Origin
が含まれていれば、CORSが設定されています。
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: Content-Type
デバッグ方法
1. Apacheのエラーログを確認
CORS設定が正しく反映されない場合は、Apacheのエラーログを確認しましょう。
tail -f /var/log/apache2/error.log
エラーメッセージが記録されている場合は、設定ミスやモジュールの問題が考えられます。
2. mod_headers
が有効か確認
mod_headers
モジュールが無効だと、CORSヘッダーが適用されません。有効かどうかを確認するには以下のコマンドを実行します。
apachectl -M | grep headers
以下のようにheaders_module
が表示されれば、有効です。
headers_module (shared)
無効の場合は、次のコマンドで有効化します。
a2enmod headers
systemctl restart apache2
3. プリフライトリクエストの確認
OPTIONS
メソッドによるプリフライトリクエストが正しく処理されているか確認します。
curl -X OPTIONS https://api.example.com -H "Origin: https://app.example.com"
200 OK
が返され、Access-Control-Allow-Methods
が含まれているかを確認してください。
よくあるエラーと対処法
- CORSヘッダーが見つからない
mod_headers
が無効の可能性があります。有効化してApacheを再起動してください。.htaccess
ファイルが適用されていない可能性があります。Apacheの設定で.htaccess
が許可されているか確認してください。
AllowOverride All
- オリジンが許可されていない
Access-Control-Allow-Origin
で正しいオリジンが指定されているか確認してください。- 必要に応じて
*
で全オリジンを許可し、一度動作を確認してから特定のオリジンに絞りましょう。
- プリフライトリクエストが失敗する
OPTIONS
メソッドが許可されているか確認し、必要ならAccess-Control-Allow-Methods
にOPTIONS
を追加してください。
次のセクションでは、CORS設定時によくある問題とその対策について詳しく解説します。
よくある問題とその対策
ApacheでCORSを設定する際には、思わぬエラーや問題が発生することがあります。ここでは、CORS設定時によくある問題とその具体的な対処法を紹介します。
1. CORSポリシーによるブロック
エラー例:
Access to fetch at 'https://api.example.com' from origin 'https://app.example.com' has been blocked by CORS policy.
原因:
Access-Control-Allow-Origin
が設定されていない、または誤ったオリジンが指定されています。mod_headers
が無効になっている。
対策:
.htaccess
またはhttpd.conf
で以下のように明示的にオリジンを指定します。
Header set Access-Control-Allow-Origin "https://app.example.com"
- すべてのオリジンを一時的に許可するには、
*
を使用します。ただし、本番環境では避けるべきです。
Header set Access-Control-Allow-Origin "*"
mod_headers
が有効か確認し、必要であれば以下のコマンドで有効化します。
a2enmod headers
systemctl restart apache2
2. プリフライトリクエストが失敗する
エラー例:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Methods' header is present on the requested resource.
原因:
OPTIONS
メソッドが許可されていない。- プリフライトリクエストに対するCORSヘッダーが不完全。
対策:
- Apacheで
OPTIONS
メソッドを許可する設定を追加します。
Header set Access-Control-Allow-Methods "GET, POST, OPTIONS"
- 必要に応じて
RewriteRule
を追加し、OPTIONS
リクエストを処理できるようにします。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
</IfModule>
3. カスタムヘッダーがブロックされる
エラー例:
Request header field Authorization is not allowed by Access-Control-Allow-Headers.
原因:
Authorization
やContent-Type
などのカスタムヘッダーが許可されていない。
対策:
Access-Control-Allow-Headers
に必要なヘッダーを追加します。
Header set Access-Control-Allow-Headers "Authorization, Content-Type"
4. ワイルドカード`*`使用時の制約
エラー例:
The 'Access-Control-Allow-Origin' header contains the invalid value '*', but it must be the same as the Origin.
原因:
- 認証付きリクエストでワイルドカード
*
が使われている場合、CORS仕様によりブロックされます。
対策:
- 認証が必要なリクエストでは、特定のオリジンを明示的に指定します。
Header set Access-Control-Allow-Origin "https://app.example.com"
5. .htaccessが適用されない
エラー例:
- CORSヘッダーがレスポンスに反映されない。
原因:
- Apacheが
.htaccess
を許可していない。
対策:
- Apacheの設定で
AllowOverride
をAll
に設定します。
<Directory /var/www/html>
AllowOverride All
</Directory>
- 設定後、Apacheを再起動します。
systemctl restart apache2
6. 設定が一部のリクエストに適用されない
原因:
- 特定のディレクトリやファイルタイプにだけCORSが適用されている可能性があります。
対策:
- グローバルにCORSを適用したい場合は、
VirtualHost
やLocation
で広範囲に設定します。
<VirtualHost *:80>
ServerName api.example.com
<Location />
Header set Access-Control-Allow-Origin "https://app.example.com"
</Location>
</VirtualHost>
次のセクションでは、ApacheでのCORS設定の総まとめを行います。
まとめ
本記事では、Apacheで異なるサブドメイン間にCORSを適用する方法について解説しました。CORSは、異なるオリジン間でリソースを安全に共有するための重要な仕組みであり、特にサブドメイン間の通信で多く利用されます。
ApacheでCORSを設定する基本から、サブドメインごとの細かい設定、.htaccess
を使った手軽な管理方法、プリフライトリクエストの処理、そしてよくある問題とその対策まで、実践的なアプローチを詳しく説明しました。
CORSの設定を適切に行うことで、サブドメイン間のリソース共有がスムーズになり、セキュリティを維持しながらWebアプリケーションを柔軟に構築できます。もしCORSエラーが発生した場合は、ブラウザの開発者ツールやcurl
を活用して迅速にデバッグし、正しい設定を反映させましょう。
安全で効率的なWebアプリケーション開発のために、CORS設定の知識を活用してください。
コメント