AWSでCORSをちゃんと理解したい人のためのメモ
このメモはこんな人向け
- AWSでS3やAPI Gatewayなどを使ってWebサービスを作っている方
- CORSの仕組みや設定でつまずいたことがある方
- 「バケットポリシーやIAMポリシーとCORSの違いがよく分からない」と感じている方
この記事で得られること
- CORSの基本的な仕組みとAWSでの具体的な設定方法が分かる
- サービスごとのCORS設定のポイントやユースケースが分かる
- よくあるエラーやトラブルの対処法も知ることができる
前提知識
- AWSマネジメントコンソールの基本操作ができる
- WebアプリやAPIの開発経験が少しでもある
目次
- はじめに
- CORSって何?
- CORSのざっくり仕組み
- AWSでCORSを設定できるサービス
- S3
- API Gateway
- Lambda(Function URLs)
- CloudFront
- CORSとバケットポリシー・他の認可方式の違い
- バケットポリシーとの違い
- IAMポリシーとの違い
- CloudFrontのオリジンポリシーとの違い
- よくあるCORSエラーとその対処法
- まとめ
1. はじめに
「CORSってよく聞くけど、正直よく分かってない…」とか「AWSでCORS設定したのに動かない!」みたいな経験、ありませんか?自分はあります!!
自分も最初は混乱したので、整理がてらまとめてみました。AWSのS3やAPI Gatewayを例に、CORSの基本やバケットポリシーとの違いもざっくり解説します。
2. CORSとは何か?
CORS(Cross-Origin Resource Sharing)は、異なるドメイン(オリジン)からのアクセスをどう扱うかを決める仕組みです。
たとえば、https://hoge.comのWebアプリがhttps://api.fuga.comのAPIを利用したい場合、何も設定しないとブラウザが「怪しい」と判断してブロックします。そこでCORSの設定が必要になります。
昔から「悪意のあるサイトが勝手に他のサイトのデータを盗む」などの攻撃(クロスサイトリクエストフォージェリや情報抜き取り)が多かったため、ブラウザは「オリジン(ドメイン)が違うリクエストは一旦止めておこう」というルールでユーザーを守っています。
(参考: https://developer.mozilla.org/ja/docs/Web/HTTP/Guides/CORS)
3. CORSの基本的な仕組み
ブラウザがAPIにリクエストを送信する際、自動的にOriginというヘッダーが付与されます。
サーバー側は「Access-Control-Allow-Origin」というヘッダーで「このオリジンからのアクセスは許可します」と返します。
また、PUTやDELETEなどの特定のメソッドやカスタムヘッダーを利用する場合は、「プリフライトリクエスト(OPTIONS)」が送信され、事前にサーバーが許可するかどうかを確認します。
CORSの通信フロー図(マーメイド)
Originヘッダーとは?
ブラウザがAPIなどにリクエストを送信する際、自動的にOriginというヘッダーが付与されます。
この中身は「どこからリクエストが来たか」を示すURL(スキーム+ドメイン+ポート)です。
例:
Origin: https://hoge.com
Access-Control-Allow-Originヘッダーとは?
サーバー側がレスポンスで返すヘッダーで、「このオリジンからのアクセスはOKです」と伝える役割があります。
例:
Access-Control-Allow-Origin: https://hoge.com
このように返すと、https://hoge.comからのリクエストだけが許可されます。
すべてのオリジンを許可したい場合は、
Access-Control-Allow-Origin: *
と記述します(ただし認証情報付きリクエストでは利用できません)。
4. AWSでCORSを設定できるサービス
ここでは、3章で説明したCORSの仕組みをもとに、AWSの各サービスごとに「用途」「ブラウザ側」「サーバ側」の具体例を紹介します。
S3
用途
静的ウェブサイトのホスティングや画像・ファイル配信など。
ユースケース
- 社内ポータルでS3に置いたマニュアルPDFを配信したい。社内ドメインだけ許可して外部はブロックしたい
- React製SPAからS3の画像を直接読み込みたい。特定のWebアプリだけ許可したい
設定方法
S3バケットの「プロパティ」→「CORS設定」から、許可したいオリジンやメソッドをXML形式で記述します。
ポイント
S3バケットのCORS設定で、どのオリジン・メソッドを許可するかをXMLで記述します。
例:
<CORSRule>
<AllowedOrigin>https://hoge.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
レスポンス例:
Access-Control-Allow-Origin: https://hoge.com
API Gateway
用途
REST APIやWeb APIの公開。
ユースケース
- スマホアプリからAPI Gateway経由でデータを取得したい。アプリのドメインだけ許可したい
- 外部のパートナー企業向けにAPIを公開。特定のパートナーサイトだけCORS許可
設定方法
API Gatewayの「リソース」画面で「CORSの有効化」を選択し、許可するオリジンやメソッドを指定します。
ポイント
API GatewayのCORS設定で、許可するオリジンやメソッドを指定します。
レスポンス例:
Access-Control-Allow-Origin: https://hoge.com
Access-Control-Allow-Methods: GET,POST,OPTIONS
Lambda(Function URLs)
用途
サーバーレスでAPIやWebサービスを提供。
ユースケース
- 社内ツールのバックエンドをLambdaで構築。社内WebアプリだけCORS許可
- 一時的なWebhook受信APIをLambdaで作り、特定サービスからのリクエストだけ許可
設定方法
Lambda関数のコード内で、レスポンスヘッダーにAccess-Control-Allow-Originなどを明示的に追加します。
ポイント
Lambda関数のレスポンスでCORSヘッダーを明示的に返します。
例:
{
"statusCode": 200,
"headers": {
"Access-Control-Allow-Origin": "https://hoge.com"
},
"body": "..."
}
CloudFront
用途
CDNとしてS3やAPI Gatewayのリソースを配信。
ユースケース
- グローバルなWebサービスでCloudFront経由で画像を配信。自社サイトだけCORS許可
- CloudFrontでAPI GatewayのAPIをキャッシュ配信。特定のWebアプリだけ許可
設定方法
CloudFrontの「動作」設定でレスポンスヘッダーを追加するか、オリジンサーバー側でCORSヘッダーを返すようにします。
ポイント
CloudFrontのレスポンスヘッダー設定や、オリジンサーバー(S3やAPI Gateway)側でCORSヘッダーを返すようにします。
レスポンス例:
Access-Control-Allow-Origin: https://hoge.com
5. CORSとバケットポリシー・他の認可方式との違い
バケットポリシーとの違い
バケットポリシーは「誰がどの操作をできるか」を制御する認可設定です。一方、CORSは「どのオリジン(ドメイン)からのリクエストをブラウザ経由で許可するか」を制御します。バケットポリシーだけでは、ブラウザのCORS制限は回避できません。
CORSとバケットポリシーの違い
IAMポリシーとの違い
IAMポリシーはAWSリソースへのアクセス権限をユーザーやロール単位で管理します。CORSはHTTPリクエストのオリジン制御であり、役割が異なります。
CloudFrontのオリジンポリシーとの違い
CloudFrontのオリジンポリシーは、どのオリジンからリソースを取得するかの設定です。CORSはクライアント(主にブラウザ)とサーバー間の通信制御です。
6. まとめ
CORSはWebアプリとAWSサービスを連携させる上で重要な知識です。バケットポリシーやIAMポリシーと混同せず、役割を正しく理解して設定することで、安全かつ柔軟なシステムを構築できます。
もしCORSで困ったときは、この記事を参考にしてみてください。