AWS日記47(API Gateway - CORS)

# はじめに
今回はREST API リソースの CORS サポートを有効にします
[REST API リソースの CORS を有効にする](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/how-to-cors.html)を参考に、POST メソッドリクエストに対する設定を行います


# 準備

### CloudFormation
```yaml
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: SampleJsonResponse Page

Parameters:
  ApplicationName:
    Type: String
    Default: 'SampleJsonResponsePage'

Resources:
  FrontPageApi:
    Type: AWS::Serverless::Api
    Properties:
      Name: SampleJsonResponsePageApi
      EndpointConfiguration: REGIONAL
      StageName: Prod
  FrontPageFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: SampleJsonResponsePageFunction
      Handler: bootstrap
      Runtime: provided.al2
      Timeout: 5
      CodeUri: target/lambda/sample_json_response/
      MemorySize: 256
      Architectures: ["arm64"]
      Description: 'SampleJsonResponse Function'
      Events:
        testapi:
          Type: Api
          Properties:
            Path: '/api/sample'
            Method: post
            RestApiId: !Ref FrontPageApi

Outputs:
  FunctionName:
    Value: !Ref FrontPageFunction
    Description: Name of the Lambda function
  APIURI:
    Description: "URI"
    Value: !Join ['', ['https://', !Ref FrontPageApi, '.execute-api.', !Ref 'AWS::Region', '.amazonaws.com/', 'Prod/']]
```

# Lambda設定
### レスポンスヘッダー追加
```rust
    let mut map = HeaderMap::new();
    map.append(header::ACCESS_CONTROL_ALLOW_ORIGIN, "https://www.example.com".parse().unwrap());
    map.append(header::ACCESS_CONTROL_ALLOW_HEADERS, "Content-Type".parse().unwrap());
    map.append(header::ACCESS_CONTROL_ALLOW_METHODS, "POST".parse().unwrap());
    Ok(
        ApiGatewayProxyResponse {
            status_code: 200,
            body: Some(resp_json.to_string().into()),
            is_base64_encoded: None,
            headers: map,
            multi_value_headers: HeaderMap::new()
        }
    )
```

# API Gateway設定

![02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586707/99d7520d-7ac2-d71b-2246-6ffc556665e3.jpeg)


![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586707/feb3e2ae-728e-16a5-11d1-3627c14d494e.jpeg)

- POSTメソッドのレスポンスヘッダーを追加する
  - Access-Control-Allow-Headers
  - Access-Control-Allow-Methods
  - Access-Control-Allow-Origin


# 確認
- ローカルサーバーからAPIにリクエストする
![07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586707/c5543e26-975a-c383-efc5-00cb404df2c3.jpeg)

Originが異なるためブロックされる

# 終わりに
Lambda側だけでなく、API Gateway側の設定も必要なので初回は混乱しました。

[AWS デベロッパーガイド](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/how-to-cors.html)の他に以下の記事を参考にしました。

[API Gateway + Lambda のCORS関連エラーの対策](https://qiita.com/shin1kt/items/db6bae7fbe70573d530a)

[API Gateway の Lambda プロキシ統合のCORS対応をまとめてみる](https://dev.classmethod.jp/articles/apigateway-lambda-proxy-cors/)


##### 追記
AWS Serverless Application Model (AWS SAM) テンプレート に 「Cors」 の設定をすることで、本文の 「API Gateway設定」 を行う必要がなくなります。
参考資料 : [CorsConfiguration](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-property-api-corsconfiguration.html)

```yaml
      Cors:
        AllowMethods: "'POST'"
        AllowHeaders: "'Content-Type,Origin'"
        AllowOrigin: "'https://www.example.com'"
        MaxAge: "'600'"
        AllowCredentials: true
```