4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Amazon API GatewayでサクッとCORS対応する

Posted at

はじめに

Amazon API GatewayとS3の静的Webサイトホスティングを組み合わせると、サーバレスで何でもできるようになるのだけど、当然のことながらオリジンが変わってしまうので、CORSの設定が必要。
マネコンからは一発でCORSの設定を入れることができるものの、IaCと組み合わせてると、マネコンからの変更は色々と不都合があるので、ここはTerraform一撃でCORSの設定を入れられるようにしてしまおう。

CORSって何?という人はクラメソ先生に教えてもらおう!

簡単なリクエスト編(GETメソッド)

GETについては、レスポンスのheadersでCORSを許容することを示せば良い。

具体的には、Access-Control-Allow-HeadersAccess-Control-Allow-OriginAccess-Control-Allow-Methodsを返す。

以下はPython+API Gatewayの統合レスポンスで返す場合の例。

    return {
        'isBase64Encoded': False,
        'statusCode': status_code,
        'headers': {
            "Access-Control-Allow-Headers" : "*",
            "Access-Control-Allow-Origin": "[許容するオリジン]",
            "Access-Control-Allow-Methods": "GET"
        },
        'body': json.dumps(body)
    }

プリフライトリクエスト編(OPTIONメソッド)

プリフライトリクエストについては、Lambdaで実装しても良いが、いちいちLambdaなんて作っていられないので、API Gatewayの統合でMockを使うことにする。

まずは、API GatewayのRESTAPIと、リソースを作成し、

resource "aws_api_gateway_rest_api" "test" {
  name        = local.api_gateway_name
  description = "テスト用API Gateway"
}

resource "aws_api_gateway_resource" "test" {
  rest_api_id = aws_api_gateway_rest_api.test.id
  parent_id   = aws_api_gateway_rest_api.test.root_resource_id
  path_part   = "test"
}

OPTIONメソッドを定義する。

resource "aws_api_gateway_method" "test_options" {
  rest_api_id   = aws_api_gateway_rest_api.test.id
  resource_id   = aws_api_gateway_resource.test.id
  http_method   = "OPTIONS"
  authorization = "NONE"
}

testのOPTIONメソッドに対する統合レスポンスを作りつつ、メソッドレスポンスでCORSのヘッダを透過するよう設定し、

resource "aws_api_gateway_method_response" "test_options_200" {
  rest_api_id = aws_api_gateway_rest_api.test.id
  resource_id = aws_api_gateway_resource.test.id
  http_method = aws_api_gateway_method.test_options.http_method
  status_code = "200"

  response_models = {
    "application/json" = "Empty"
  }

  response_parameters = {
    "method.response.header.Access-Control-Allow-Headers" = true,
    "method.response.header.Access-Control-Allow-Methods" = true,
    "method.response.header.Access-Control-Allow-Origin"  = true
  }
}

resource "aws_api_gateway_integration_response" "test_options" {
  rest_api_id = aws_api_gateway_rest_api.test.id
  resource_id = aws_api_gateway_resource.test.id
  http_method = aws_api_gateway_method.test_options.http_method
  status_code = aws_api_gateway_method_response.test_options_200.status_code

  response_parameters = {
    "method.response.header.Access-Control-Allow-Headers" = "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'",
    "method.response.header.Access-Control-Allow-Methods" = "'GET,OPTIONS,POST,PUT'",
    "method.response.header.Access-Control-Allow-Origin"  = "'[許容するオリジン]'"
  }
}

testパスのOPTIONSメソッドに対して200応答をするモックを作成する。

resource "aws_api_gateway_integration" "test_options_mock" {
  rest_api_id = aws_api_gateway_rest_api.test.id
  resource_id = aws_api_gateway_resource.test.id
  http_method = aws_api_gateway_method.test_options.http_method
  type        = "MOCK"

  request_templates = {
    "application/json" = <<EOF
{
  "statusCode": 200
}
EOF
  }
}

これでOPTIONリクエストに良い感じにCORS許容のレスポンスをしてくれるモックが作れた!
あとは好きなようにPOSTなりPUTのメソッドでCORSな更新系リクエストを作れるぞ!

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?