Amazon API GatewayのAWSサービス統合でCORS有効化をAWS CDKで設定する方法

こんにちは。サービスグループの武田です。バックエンドとしてAWS Step Functionsと統合するのを例に、AWS CDKのAwsIntegrationでCORSを有効化する方法を紹介します。
2022.01.31

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。サービスグループの武田です。

AWSでREST APIを開発する方法のひとつとしてAmazon API Gatewayがあります。API GatewayのバックエンドとしてLambda関数を指定するケースが多いのですが、他のAWSサービスも指定できます。

さて開発においてセキュリティの考慮は常に必要ですが、REST APIでの考慮事項のひとつにCORS(Cross-Origin Resource Sharing)があります。CORSとはオリジン間リソース共有とも呼ばれるもので、異なるオリジンサーバーからのアクセスを許可するかどうかという設定です。

たとえば構築したAPIのエンドポイントがhttps://abcdefghij.execute-api.ap-northeast-1.amazonaws.com/prod/だったとします。そうすると、デフォルトではhttps://abcdefghij.execute-api.ap-northeast-1.amazonaws.com以外のオリジンで動作しているWebアプリケーションからのリクエストは拒否されます。受け付けるためにはCORSの設定が必要になります。今回はバックエンドとしてAWS Step Functionsと統合するのを例に、AWS CDKのAwsIntegrationでCORSを有効化する方法を紹介します。

環境

ソースコードはAWS CDK 2.8.0での動作確認をしています。

ポイントは3ヵ所のCORS設定

CORSを有効化するCDKのソースは次のようになります。

import { aws_apigateway as apigw, Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class AmaterasuStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const restApi = new apigw.RestApi(this, 'RestApi', {
      defaultCorsPreflightOptions: {
        allowOrigins: apigw.Cors.ALL_ORIGINS,
      },
    });

    restApi.root.addResource('status').addMethod(
      'POST',
      new apigw.AwsIntegration({
        service: 'states',
        action: 'DescribeExecution',
        options: {
          passthroughBehavior: apigw.PassthroughBehavior.NEVER,
          integrationResponses: [
            {
              statusCode: '200',
              responseTemplates: {
                'application/json': '',
              },
              responseParameters: {
                'method.response.header.Access-Control-Allow-Origin': "'*'",
              },
            },
          ],
          requestTemplates: {
            'application/json': '',
          },
        },
      }),
      {
        methodResponses: [
          {
            statusCode: '200',
            responseModels: {
              'application/json': apigw.Model.EMPTY_MODEL,
            },
            responseParameters: {
              'method.response.header.Access-Control-Allow-Origin': true,
            },
          },
        ],
      }
    );
  }
}

9行目のdefaultCorsPreflightOptionsで設定しているのはCORSのプリフライトを許可するものです。この辺の細かい仕様は次のエントリなどを参考にしてください。

27行目は統合レスポンスを設定している部分で、クライアントに返すレスポンスのヘッダーにAccess-Control-Allow-Origin: '*'を追加しています。

44行目はメソッドレスポンスを設定している部分で、レスポンスヘッダーにAccess-Control-Allow-Originを含めることを許可しています。

以上の設定をすることで、/statusへのリクエストをクロスオリジンで実行可能となります。

まとめ

CDKでのCORS設定は、Lambda関数との統合ではやったことがあったのですが、AWSサービス統合は経験がありませんでした。そもそもAWSサービス統合のCORS設定自体がはじめてだったため、何の設定をすればいいのかから調べる必要がありました。ヘッダーの指定も、最初header.Access-Control-Allow-Originと書いてエラーになるなど慣れていないとはまりどころが多かったです。CORS設定をする際に役に立てば幸いです。

参考URL