【问题标题】:Getting access denied due to origin blocked by CORS in AWS Api-Gateway由于来源被 AWS Api-Gateway 中的 CORS 阻止而被拒绝访问
【发布时间】:2022-01-12 01:19:12
【问题描述】:

我有一个 AWS SAM 模板,它在 API Gateway 中创建 lambda 函数和 post 方法。默认情况下,它使用 Lambda 代理集成,当我通过 PostMan 工具进行测试时它工作正常,但是当我将 API 网关 URL 与我的沙盒应用程序一起使用时,它显示以下错误。

Access to XMLHttpRequest at 'https://abcdef.execute-api.eu-west-2.amazonaws.com/dev/my-api' from origin 'https://abcd.csb.app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

但是当我手动创建 API 网关发布方法并尝试时,它工作正常。

Lambda 函数还在响应中返回以下标头。

response = {
        'statusCode': status_code,
        'headers': {
            'Access-Control-Allow-Headers': 'Content-Type',
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'OPTIONS,POST'
        },
        'body': json.dumps(response_data)
    }

以下是 AWS SAM 模板。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  AWS SAM Template

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 10

Parameters:
  DeploymentEnv:
    Type: String

Resources:
  ApiGatewayApi:
    DependsOn: LambdaFunction
    Type: AWS::Serverless::Api
    Properties:
      StageName: !Ref DeploymentEnv
      EndpointConfiguration: 
        Type: REGIONAL
      Cors:
        AllowMethods: "'POST,OPTIONS'"
        AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key'"
        AllowOrigin: "'*'"
        MaxAge: "'600'"
        AllowCredentials: false
      Auth:
        DefaultAuthorizer: NONE
        ApiKeyRequired: true # sets for all methods
  
  LambdaFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      FunctionName: !Join [ "", [ !Ref DeploymentEnv, "-my-lambda"]]
      CodeUri: my_api/
      Handler: app.lambda_handler
      Runtime: python3.9
      Architectures:
        - x86_64
      Events:
        EventTriggerlambda:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties: 
            RestApiId: !Ref ApiGatewayApi
            Path: /my-api
            Method: POST
            Auth:
              ApiKeyRequired: true
      Role: Role_URN
      Environment:
        Variables:
          URI: Test
          USER_NAME: Test
          PASSWORD: Test
  
  ApiKey:
    Type: AWS::ApiGateway::ApiKey
    DependsOn: ApiGatewayApiStage
    Properties:
      Name: !Join ["", [{"Ref": "AWS::StackName"}, "-apikey"]]
      Enabled: true
      StageKeys:
        - RestApiId: !Ref ApiGatewayApi
          StageName: !Ref DeploymentEnv
  
  UsagePlan:
    DependsOn: 
      - ApiGatewayApiStage
    Type: AWS::ApiGateway::UsagePlan
    Properties:
      ApiStages:
        - ApiId: !Ref ApiGatewayApi
          Stage: !Ref DeploymentEnv
      Throttle:
        BurstLimit: 500
        RateLimit: 100
      UsagePlanName: MY-UsagePlan
      
  UsagePlanKey:
    Type: AWS::ApiGateway::UsagePlanKey
    Properties:
      KeyId: !Ref ApiKey
      KeyType: API_KEY
      UsagePlanId: !Ref UsagePlan

Outputs:
  LambdaFunction:
    Description: "Lambda Function ARN"
    Value: !GetAtt LambdaFunction.Arn

请帮忙,谢谢:)

【问题讨论】:

    标签: amazon-web-services aws-lambda aws-api-gateway aws-sam


    【解决方案1】:

    配置不适用于 AWS SAM 模板中 API-Gateway 中的 API 创建。因为 SAM 部署默认使用 lambda 代理集成,这就是为什么在方法响应中,需要的值很少,无法使用上述配置自动设置。因此,我使用开放 API 规范定义了 Rest API 配置,并且在部署后无需任何人工干预即可正常工作。

    以下配置即可。

    ApiGatewayApi:
        DependsOn: LambdaFunction
        Type: AWS::Serverless::Api
        Properties:
          StageName: !Ref DeploymentEnv
          DefinitionBody:
              'Fn::Transform':
                Name: 'AWS::Include'
                Parameters:
                  Location: !Join [ '', [ 's3://mybucket', '/openapi-spec.yaml'  ] ]
          EndpointConfiguration: 
            Type: REGIONAL
    

    OpenAPI 配置

    openapi: "3.0.1"
    info:
      title: "test-api"
      description: "Created by AWS Lambda"
      version: "2022-01-07T18:00:40Z"
    
    paths:
      /test-api:
        post:
          responses:
            "200":
              description: "200 response"
              headers:
                Access-Control-Allow-Origin:
                  schema:
                    type: "string"
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Empty"
          x-amazon-apigateway-integration:
            httpMethod: "POST"
            uri:  
              Fn::Sub: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunction.Arn}/invocations"
            responses:
              default:
                statusCode: "200"
                responseParameters:
                  method.response.header.Access-Control-Allow-Origin: "'*'"
            passthroughBehavior: "when_no_match"
            contentHandling: "CONVERT_TO_TEXT"
            type: "aws_proxy"
        options:
          responses:
            "200":
              description: "200 response"
              headers:
                Access-Control-Allow-Origin:
                  schema:
                    type: "string"
                Access-Control-Allow-Methods:
                  schema:
                    type: "string"
                Access-Control-Allow-Headers:
                  schema:
                    type: "string"
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/Empty"
          x-amazon-apigateway-integration:
            responses:
              default:
                statusCode: "200"
                responseParameters:
                  method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
                  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-Origin: "'*'"
            requestTemplates:
              application/json: "{\"statusCode\": 200}"
            passthroughBehavior: "when_no_match"
            type: "mock"
        x-amazon-apigateway-any-method:
          responses:
            "200":
              description: "200 response"
              content: {}
          security:
          - api_key: []
          x-amazon-apigateway-integration:
            httpMethod: "POST"
            uri: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${LambdaFunction.Arn}/invocations"
            responses:
              ".*":
                statusCode: "200"
            passthroughBehavior: "when_no_match"
            type: "aws_proxy"
    components:
      schemas:
        Empty:
          title: "Empty Schema"
          type: "object"
      securitySchemes:
        api_key:
          type: "apiKey"
          name: "x-api-key"
          in: "header"
    
    

    此处的 openapi-spec.yaml 文件与 AWS SAM 模板保存在同一文件夹中,并在部署开始之前使用 GitHub 工作流管道文件中的以下命令上传到 S3 存储桶。

    - run: aws s3 cp openapi-spec.yaml s3://mnai-code-deployments
            - run: sam build
            - run: sam deploy --no-confirm-changeset --no-fail-on-empty-changeset --stack-name my-stack --s3-bucket mybucket  --capabilities CAPABILITY_IAM --region eu-west-2 --parameter-overrides ParameterKey=DeploymentEnv,ParameterValue=dev ParameterKey=S3Bucket,ParameterValue=mybucket
    

    谢谢

    【讨论】:

      猜你喜欢
      • 2019-11-03
      • 1970-01-01
      • 2022-09-30
      • 1970-01-01
      • 2021-07-13
      • 2021-04-12
      • 2015-11-01
      • 1970-01-01
      • 2016-08-13
      相关资源
      最近更新 更多