API GatewayでCORSを有効にするためにやったこと
はじめに
AWS API Gatewayをつかっていて、CORSまわりの設定が地味に時間を削ってきたので、後陣のためにメモっておきたい
CORS関連のヘッダがつかない..
API GatewayのLambda Proxy Integration
(ラムダプロキシ統合、以降LPI)を使っている場合、Enable CORS
をするだけでは、いい感じのCORS関連ヘッダーをつけてくれない(その他の統合方法だとやってくれるのだが..)
どんなレスポンスヘッダの設定になってんのかなと、Integration Response
(統合レスポンス)を見にいくも、グレーアウトされている。LPI以外だと、ここでヘッダつけてくれるんだと思う[1]
どうすればいいのか?
LPIを使ってる状況でCORSを許可したい時は以下の三つをすればよいようだ(たぶん)
- Lambda側でヘッダを返す
- Preflightを使えるように
OPTIONS
のAuthorization
をNONE
にしておく[2] - エラーレスポンスがCORSで弾かれないように、エラーレスポンスにもヘッダをつける
1. Lambda側でヘッダを返す
コード内で、ヘッダをつけるようにする
def lambda_handler(event:, context:)
:
:
{
statusCode: 200,
headers: {
"Access-Control-Allow-Headers": "Content-Type",
"Access-Control-Allow-Origin": '*',
"Access-Control-Allow-Methods": "OPTIONS,POST,GET"
},
body: JSON.generate(list_project(table))
}
:
:
end
OPTIONS
のAuthorization
をNONE
にしておく
2. API Gateway
>API
>OPTIONS
3. エラーレスポンスにもヘッダをつける
- だけだと、ラムダまで届かない(API Gatewayでエラーになる等)場合のレスポンスはヘッダがつかなくて、ブラウザでCORSでブロックされる。そうなると、何が起こってるのかわからず、一見CORSのエラーに見えるけど認証エラーだったとか、切り分けがややこしいのでやっておくとよい
API Gateway
>API
>Gateway Response
>Default 4xx
とDefault 5xx
あたり
公式ドキュメントはどうなっているか
しっかり読めばわかるんだろうけど、「なんでそうなってんの?」がわかりにくい
重要
上記の手順をプロキシ統合の ANY メソッドに適用すると、適切な CORS ヘッダーは設定されません。代わりに、バックエンドは Access-Control-Allow-Origin などの適切な CORS ヘッダーを返す必要があります。
実際やってみたけど、ANYじゃなくてもCORSのヘッダーはつかないんだな...
Lambda または HTTP プロキシ統合への CORS のサポートを有効にする
Lambda プロキシ統合、または HTTP プロキシ統合の場合、API Gateway で必要な OPTIONS レスポンスヘッダーを引き続き設定できます。ただし、プロキシ統合は統合レスポンスを返さないため、バックエンドは Access-Control-Allow-Origin および Access-Control-Allow-Headers を返します。
OPTIONS
だけは、いい感じでやってくれているようなんですが、なんでOPTIONS
だけ?
あ、あと、API Gatewayの変更はDeployしないと反映されないので、そこもうっかり忘れてハマりがち。また、Deployの反映は数分かかるので落ち着いて待つこと
シリーズ
- Lambda ↔ DynamoDB
- API Gateway ↔ Lambda ↔ DynamoDB
- Cognito ↔ API Gateway ↔ Lambda ↔ Dynamo
- Amplify [Hosting] ↔ API Gateway [REST] ↔ Lambda
- API GatewayでCORSを有効にするためにやったこと
- AmplifyのJavascript SDKでCognito認証からデータ取得まで
Discussion