API Gateway + Lambda のCORS関連エラーの対策


API Gateway と Lambda でウェブアプリのAPIエンドポイントをつくって外部サイトのシステムから呼び出そうとしたらCORS(Cross-origin resource sharing)のエラーになってしまい、設定に躓いたのでメモ

基本的な対策

API Gateway でCORS有効化

API Gateway のアクションからCORSの有効化を設定するのが基本的な対策です。
通常はこれでOKのはず。

エラーが出て設定が反映できないとき

自分の環境で、以下のようなエラーがでてうまく設定ができませんでした。
Invalid Response status code specified

対策(レスポンスヘッダーを手動で設定)

  1. 上記画面でエラーになった内容をメモ
  2. リソースからエラーになっているメソッド(GETとかPOSTとか)を選択
  3. レスポンスの追加を選択
  4. HTTPのステータスに200を入力して確定(チェックマークみたいなのをクリック)
  5. 200の左あたりに▶が表示されるのでそれをクリックして開く
  6. 200のレスポンスヘッダーの入力欄が表示されるのでエラーになっていたヘッダーを設定

画面


↑ここを選択して

↑こんな風に手動設定

確認する

上記を修正して、もういちどCORSの有効化をおこなうと、ヘッダーを記入したメソッドはエラーが解消されている。
全てのメソッドに対して上記方法で手動設定したところCORS有効化時のエラーがでなくなりました。
(Access-Control-Allow-Origin 統合レスポンスヘッダーマッピング)というのだけ、エラーが解消できないことがありましたが、とりあえずアクセスはできました。たぶん下のLambdaほうで解決できているのかな?と思っています。

(!)CORSの有効化をおこなったらデプロイを忘れずに!
統合なんちゃら以外エラーが解消したいのに相変わらずアクセスできない等のときは、API Gatewayのデプロイを忘れずに。(慣れている人は当たり前なのかもだけど自分はデプロイ忘れていて途方にくれました)

Lambdaのレスポンス

上記でAPI GatewayのCORSは設定できるけれど、その先がLambdaの場合は、Lambdaのレスポンスも設定しないといけないです。とりあえず全部許可する場合は、こんな感じになります。

exports.handler = async (event) => {
    const response = {
        statusCode: 200,
        headers: {
            "Access-Control-Allow-Headers" : "Content-Type",
            "Access-Control-Allow-Origin": "*",
            "Access-Control-Allow-Methods": "GET"
        },
        'body': JSON.stringify({
            message: 'hello world Test2!!',
        })
    };
    return response;
};

参考

https://stackoverflow.com/questions/45820769/fail-to-enable-cors-for-api-gateway-functions
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/how-to-cors.html