在 Cloudformation 模板中为 API 网关启用 CORS

Enable CORS for API Gateway in Cloudformation template

我正在为我的环境创建 AWS Cloudformation 模板,但我找不到为 API 网关方法启用 CORS 的方法。

我可以使用 AWS 控制台 (here is the official doc) 进行配置,但如何在 Cloudformation 模板中进行配置?

API 网关对自动 CORS 配置的支持目前只能通过 API 网关控制台工作。从 swagger 导入 API 或通过 CloudFormation 定义 API 时,您仍然可以自己 set-up CORS,但是您必须指定所有参数以设置 OPTIONS 方法以及添加CORS 特定于您的其他方法 headers。

This page 展示了如何在导入 swagger 时 set-up CORS。通过 CloudFormation 设置 CORS 在概念上类似,但使用 CloudFormation 语法而不是 swagger 语法。

经过反复试验,我发现与 CORS 控制台向导相比,以下 CloudFormation 模板片段将生成等效的 OPTIONS 方法:

OptionsMethod:
  Type: AWS::ApiGateway::Method
  Properties:
    AuthorizationType: NONE
    RestApiId:
      Ref: MyApi
    ResourceId:
      Ref: MyResourceOnWhichToEnableCORS
    HttpMethod: OPTIONS
    Integration:
      IntegrationResponses:
      - StatusCode: 200
        ResponseParameters:
          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: "'POST,OPTIONS'"
          method.response.header.Access-Control-Allow-Origin: "'*'"
        ResponseTemplates:
          application/json: ''
      PassthroughBehavior: WHEN_NO_MATCH
      RequestTemplates:
        application/json: '{"statusCode": 200}'
      Type: MOCK
    MethodResponses:
    - StatusCode: 200
      ResponseModels:
        application/json: 'Empty'
      ResponseParameters:
          method.response.header.Access-Control-Allow-Headers: false
          method.response.header.Access-Control-Allow-Methods: false
          method.response.header.Access-Control-Allow-Origin: false

*注1:这是一个POST取默认值的例子。显然,您需要更新 Access-Control-Allow-Methods 以包含您需要的值。

*注 2:感谢 AWS CloudFormation 团队最近引入了 YAML 支持。如果您需要转换 to/from YAML/JSON,我发现这个网站很方便:http://www.json2yaml.com/

试试这个:

  OPTIONS: 
   Type: AWS::ApiGateway::Method 
   Properties: ApiKeyRequired: false
   RestApiId: !Ref YourAPI 
   ResourceId: !Ref YourResourceName 
   HttpMethod: OPTIONS 
   AuthorizationType: NONE 
   Integration: 
    Type: MOCK 
    IntegrationResponses: 
     - StatusCode: 200 
     ResponseParameters: 
      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'" 
      method.response.header.Access-Control-Allow-Origin: "'*'" 
     ResponseTemplates: 
      application/json: '' 
    PassthroughBehavior: WHEN_NO_MATCH 
    RequestTemplates: 
     application/json: '{"statusCode": 200}' 
    Type: MOCK 
   MethodResponses: 
   - StatusCode: 200 
   ResponseModels: 
    application/json: 'Empty' 
   ResponseParameters: 
    method.response.header.Access-Control-Allow-Headers: false 
    method.response.header.Access-Control-Allow-Methods: false 
    method.response.header.Access-Control-Allow-Origin: false

它只创建选项方法,GET,POST,等方法响应还需要做一些工作, 我已经创建了一个完整的 hello world cloudformation

https://github.com/seraphjiang/aws-cors-cloudformation/tree/master

此代码段适用于我团队的部署。请注意,这是一个具有 ANY 方法的代理资源。

CORSOptionsMethod: # Adds cors
    Type: "AWS::ApiGateway::Method"
    Properties:
      ResourceId:
        !Ref apiProxy
      RestApiId:
        !Ref api
      AuthorizationType: NONE
      HttpMethod: OPTIONS
      Integration:
        Type: MOCK
        IntegrationResponses:
          - ResponseParameters:
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,Cache-Control'"
              method.response.header.Access-Control-Allow-Methods: "'GET,POST,PUT,DELETE,OPTIONS'"
              method.response.header.Access-Control-Allow-Origin: !Sub
                - "'${CORSOrigin}'"
                - { 'CORSOrigin': !FindInMap [Environment, !Ref Environment, CORSOrigin] }
            ResponseTemplates:
              application/json: ''
            StatusCode: '200'
        PassthroughBehavior: NEVER
        RequestTemplates:
          application/json: '{"statusCode": 200}'
      MethodResponses:
        - ResponseModels:
            application/json: Empty
          ResponseParameters:
            method.response.header.Access-Control-Allow-Headers: true
            method.response.header.Access-Control-Allow-Methods: true
            method.response.header.Access-Control-Allow-Origin: true
          StatusCode: '200'