带有 HTTP API 的 AWS SAM 中的 CORS 配置似乎被忽略

问题描述

编辑:这在第二天开始按预期工作。我很确定我没有做任何不同的事情。不知道该怎么回答这个问题。关闭删除?,就这样?

我正在使用 AWS SAM 和新的 HTTP API 网关创建一个无服务器 Web API。

这是我当前的模板文件

AWstemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  fotffleet-api

  Sample SAM Template for fotffleet-api

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 3
    CodeUri: fotffleet/
    Runtime: python3.7

Resources:
  ServerlessHttpApi:
    Type: AWS::Serverless::HttpApi
    Properties:
      CorsConfiguration:
        AllowOrigins:
          - "http://localhost:3000"
        AllowMethods:
          - GET
      DeFinitionBody:
        openapi: "3.0.1"
        info:
          title: "sam-app"
          version: "1.0"
        tags:
        - name: "httpapi:createdBy"
          x-amazon-apigateway-tag-value: "SAM"
        paths:
          /cells:
            get:
              responses:
                default:
                  description: "Default response for GET /cells"
              x-amazon-apigateway-integration:
                payloadFormatVersion: "2.0"
                type: "aws_proxy"
                httpMethod: "POST"
                uri:
                  Fn::GetAtt: [CellsFunction,Arn]
                connectionType: "INTERNET"
          /cells/{cellName}:
            get:
              responses:
                default:
                  description: "Default response for GET /cells/{cellName}"
              x-amazon-apigateway-integration:
                payloadFormatVersion: "2.0"
                type: "aws_proxy"
                httpMethod: "POST"
                uri:
                  Fn::GetAtt: [CellInfoFunction,Arn]
                connectionType: "INTERNET"
          /hello:
            get:
              responses:
                default:
                  description: "Default response for GET /hello"
              x-amazon-apigateway-integration:
                payloadFormatVersion: "2.0"
                type: "aws_proxy"
                httpMethod: "POST"
                uri:
                  Fn::GetAtt: [HelloFunction,Arn]
                connectionType: "INTERNET"
          /jobs/{cellName}:
            get:
              responses:
                default:
                  description: "Default response for GET /jobs/{cellName}"
              x-amazon-apigateway-integration:
                payloadFormatVersion: "2.0"
                type: "aws_proxy"
                httpMethod: "POST"
                uri:
                  Fn::GetAtt: [JobsFunction,Arn]
                connectionType: "INTERNET"
        x-amazon-apigateway-cors:
          maxAge: 0
          allowCredentials: false
          allowOrigins:
          - "http://localhost:3000"
        x-amazon-apigateway-importexport-version: "1.0"

  HelloFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: app.hello
      Events:
        Hello:
          Type: HttpApi
          Properties:
            Path: /hello
            Method: get
            ApiId: !Ref ServerlessHttpApi
  
  CellInfoFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: app.cell_info
      Policies:
        - AWSIoTFullAccess
      Events:
        Http:
          Type: HttpApi
          Properties:
            Path: /cells/{cellName}
            Method: get
            ApiId: !Ref ServerlessHttpApi
  
  CellsFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: app.cells
      Policies:
        - AWSIoTFullAccess
      Events:
        Http:
          Type: HttpApi
          Properties:
            Path: /cells
            Method: get
            ApiId: !Ref ServerlessHttpApi

  JobsFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: app.jobs
      Policies:
        - AmazonDynamoDBReadOnlyAccess 
      Events:
        Http:
          Type: HttpApi
          Properties:
            Path: /jobs/{cellName}
            Method: get
            ApiId: !Ref ServerlessHttpApi

Outputs:
  # Find out more about other implicit resources you can reference within SAM
  # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
  HelloWorldApi:
    Description: "API Gateway endpoint URL for Prod stage"
    Value: !Sub "https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com"

可以看出,我添加了一些 CORS 配置。在 AWS::Serverless::HttpApiDeFinitionBody 中,即 OpenAPI 规范。

我的问题是,据我所知,所有 CORS 配置都被完全忽略了。当我在更改 cors 配置后部署时,它说:

Waiting for changeset to be created..
Error: No changes to deploy. Stack sam-app is up to date

当我运行 sam validate --debug --profile [my-profile] 时,我的理解是它尝试部署的 CloudFormation 文件输出。它看起来像这样:

AWstemplateFormatVersion: '2010-09-09'
Description: 'fotffleet-api

  Sample SAM Template for fotffleet-api

  '
Resources:
  HelloFunction:
    Properties:
      Code:
        S3Bucket: bucket
        S3Key: value
      Handler: app.hello
      Role:
        Fn::GetAtt:
        - HelloFunctionRole
        - Arn
      Runtime: python3.7
      Tags:
      - Key: lambda:createdBy
        Value: SAM
      Timeout: 3
    Type: AWS::Lambda::Function
  HelloFunctionRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Action:
          - sts:AssumeRole
          Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
        Version: '2012-10-17'
      ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Tags:
      - Key: lambda:createdBy
        Value: SAM
    Type: AWS::IAM::Role
  HelloFunctionHelloPermission:
    Properties:
      Action: lambda:InvokeFunction
      FunctionName:
        Ref: HelloFunction
      Principal: apigateway.amazonaws.com
      SourceArn:
        Fn::Sub:
        - arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/hello
        - __ApiId__:
            Ref: ServerlessHttpApi
          __Stage__: '*'
    Type: AWS::Lambda::Permission
  CellInfoFunction:
    Properties:
      Code:
        S3Bucket: bucket
        S3Key: value
      Handler: app.cell_info
      Role:
        Fn::GetAtt:
        - CellInfoFunctionRole
        - Arn
      Runtime: python3.7
      Tags:
      - Key: lambda:createdBy
        Value: SAM
      Timeout: 3
    Type: AWS::Lambda::Function
  CellInfoFunctionRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Action:
          - sts:AssumeRole
          Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
        Version: '2012-10-17'
      ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      - arn:aws:iam::aws:policy/AWSIoTFullAccess
      Tags:
      - Key: lambda:createdBy
        Value: SAM
    Type: AWS::IAM::Role
  CellInfoFunctionHttpPermission:
    Properties:
      Action: lambda:InvokeFunction
      FunctionName:
        Ref: CellInfoFunction
      Principal: apigateway.amazonaws.com
      SourceArn:
        Fn::Sub:
        - arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/cells/*
        - __ApiId__:
            Ref: ServerlessHttpApi
          __Stage__: '*'
    Type: AWS::Lambda::Permission
  CellsFunction:
    Properties:
      Code:
        S3Bucket: bucket
        S3Key: value
      Handler: app.cells
      Role:
        Fn::GetAtt:
        - CellsFunctionRole
        - Arn
      Runtime: python3.7
      Tags:
      - Key: lambda:createdBy
        Value: SAM
      Timeout: 3
    Type: AWS::Lambda::Function
  CellsFunctionRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Action:
          - sts:AssumeRole
          Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
        Version: '2012-10-17'
      ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      - arn:aws:iam::aws:policy/AWSIoTFullAccess
      Tags:
      - Key: lambda:createdBy
        Value: SAM
    Type: AWS::IAM::Role
  CellsFunctionHttpPermission:
    Properties:
      Action: lambda:InvokeFunction
      FunctionName:
        Ref: CellsFunction
      Principal: apigateway.amazonaws.com
      SourceArn:
        Fn::Sub:
        - arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/cells
        - __ApiId__:
            Ref: ServerlessHttpApi
          __Stage__: '*'
    Type: AWS::Lambda::Permission
  JobsFunction:
    Properties:
      Code:
        S3Bucket: bucket
        S3Key: value
      Handler: app.jobs
      Role:
        Fn::GetAtt:
        - JobsFunctionRole
        - Arn
      Runtime: python3.7
      Tags:
      - Key: lambda:createdBy
        Value: SAM
      Timeout: 3
    Type: AWS::Lambda::Function
  JobsFunctionRole:
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Action:
          - sts:AssumeRole
          Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
        Version: '2012-10-17'
      ManagedPolicyArns:
      - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      - arn:aws:iam::aws:policy/AmazonDynamoDBReadOnlyAccess
      Tags:
      - Key: lambda:createdBy
        Value: SAM
    Type: AWS::IAM::Role
  JobsFunctionHttpPermission:
    Properties:
      Action: lambda:InvokeFunction
      FunctionName:
        Ref: JobsFunction
      Principal: apigateway.amazonaws.com
      SourceArn:
        Fn::Sub:
        - arn:${AWS::Partition}:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/jobs/*
        - __ApiId__:
            Ref: ServerlessHttpApi
          __Stage__: '*'
    Type: AWS::Lambda::Permission
  ServerlessHttpApi:
    Properties:
      Body:
        info:
          title:
            Ref: AWS::StackName
          version: '1.0'
        openapi: 3.0.1
        paths:
          /cells:
            get:
              responses: {}
              x-amazon-apigateway-integration:
                httpMethod: POST
                payloadFormatVersion: '2.0'
                type: aws_proxy
                uri:
                  Fn::Sub: arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${CellsFunction.Arn}/invocations
          /cells/{cellName}:
            get:
              parameters:
              - in: path
                name: cellName
                required: true
              responses: {}
              x-amazon-apigateway-integration:
                httpMethod: POST
                payloadFormatVersion: '2.0'
                type: aws_proxy
                uri:
                  Fn::Sub: arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${CellInfoFunction.Arn}/invocations
          /hello:
            get:
              responses: {}
              x-amazon-apigateway-integration:
                httpMethod: POST
                payloadFormatVersion: '2.0'
                type: aws_proxy
                uri:
                  Fn::Sub: arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HelloFunction.Arn}/invocations
          /jobs/{cellName}:
            get:
              parameters:
              - in: path
                name: cellName
                required: true
              responses: {}
              x-amazon-apigateway-integration:
                httpMethod: POST
                payloadFormatVersion: '2.0'
                type: aws_proxy
                uri:
                  Fn::Sub: arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${JobsFunction.Arn}/invocations
        tags:
        - name: httpapi:createdBy
          x-amazon-apigateway-tag-value: SAM
    Type: AWS::ApiGatewayV2::Api
  ServerlessHttpApiApiGatewayDefaultStage:
    Properties:
      ApiId:
        Ref: ServerlessHttpApi
      AutoDeploy: true
      StageName: $default
      Tags:
        httpapi:createdBy: SAM
    Type: AWS::ApiGatewayV2::Stage
Outputs:
  HelloWorldApi:
    Description: API Gateway endpoint URL for Prod stage
    Value:
      Fn::Sub: https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com

我不知道这应该是什么样子,但我觉得奇怪的是那里根本没有提到任何与 CORS 相关的内容

我尝试了许多变体,例如:CORS 设置仅在属性中,仅在 openAPI 定义中,没有定义主体并让 SAM 生成它,将其放在单独的文件中。

无论我做什么,就好像 SAM 完全无声地忽略任何 cors 设置。

如果不是很明显,我想知道该怎么做才能让 SAM 在部署时应用这些 CORS 设置。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)