【问题标题】:AWS SAM configure cors to run locallyAWS SAM 将 cors 配置为在本地运行
【发布时间】:2020-08-30 20:08:27
【问题描述】:

如何配置 cors 以在本地运行 lambda 函数

我尝试了不同的方法,但无法得到正确的解决方案。

下面是我的template.yml

Resources:
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: dev
      Cors:
        AllowHeaders: "'Content-Type,Authorization,Origin,X-Requested-With,Accept,x-id-token,x-custom-header'"
        AllowOrigin: "'*'"
        AllowMethods: "'OPTIONS,POST,GET,PUT,DELETE'"
        AllowCredentials: "'*'"
      Auth:
        AddDefaultAuthorizerToCorsPreflight: False
        DefaultAuthorizer: MyLambdaTokenAuthorizer
        Authorizers:
          MyLambdaTokenAuthorizer:
            FunctionArn: !GetAtt MyAuthFunction.Arn

  HelloFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: functions/hello/handler.hello
      CodeUri: "."
      Events:
        HelloAPI:
          Type: Api
          Properties:
            Path: /hello
            Method: GET
            RestApiId: !Ref MyApi

这是我的处理函数

exports.hello = async (event) => {
    const response = {
        statusCode: 200,
        headers: {
            "Access-Control-Allow-Origin": "*", // Required for CORS support to work
            "Content-Type": "application/json",
            "Access-Control-Allow-Credentials": true, // Required for cookies, authorization headers with HTTPS
        },
        body: JSON.stringify({ message: "Hello World!" }),
    };

    callback(null, response);
};

还是报错:

 No 'Access-Control-Allow-Origin' header is present on the requested resource.

【问题讨论】:

    标签: aws-lambda serverless aws-sam


    【解决方案1】:

    由于适用于 CORS 的 API Gateway 上的 AWS 文档非常糟糕,因此将回答这个问题以供将来参考。和这狗混战了将近三天,最终结果如下。

    首先,在你的SAM模板的AWS::Serverless::Api段中,配置CORS,例如:

        Type: AWS::Serverless::Api
        Properties:
          StageName: prod
          Cors:
            AllowHeaders: "'*'"
            AllowOrigin: "'*'"
            AllowCredentials: "'*'"
            AllowMethods: "'*'"
    

    接下来,创建一个愚蠢的虚拟 lambda 来处理任何 OPTIONS 请求,确保该 lambda 设置响应的标头。像这样的:

    export const handler = async (
      event: APIGatewayProxyEvent
    ): Promise<APIGatewayProxyResult> => {
      return {
        headers: {
          "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
          "Access-Control-Allow-Headers" : "*", // Required for CORS support to work
          "Access-Control-Allow-Credentials" : true // Required for cookies, authorization headers with HTTPS
        },
        statusCode: 200
      };
    }
    

    最后,在您的 SAM 模板中,收集所有端点并将它们指向这个愚蠢的 lambda。

      OptionHandler:
        Type: AWS::Serverless::Function
        Properties:
          Handler: <lambda above>
          Runtime: nodejs14.x
          Architectures:
            - arm64
          Timeout: 2
          Events:
            Method1APIOptions:
              Type: Api
              Properties:
                Path: /path/{param}
                Method: options
                RestApiId:
                  Ref: ApiGatewayApi
            Method2APIOptions:
              Type: Api
              Properties:
                Path: /path2/{param}
                Method: options
                RestApiId:
                  Ref: ApiGatewayApi
            Method3APIOptions:
              Type: Api
              Properties:
                Path: /path3/{params}
                Method: options
                RestApiId:
                  Ref: ApiGatewayApi
    

    现在每次使用 sam deploy 部署此 API 时,CORS 都不会搞砸。

    【讨论】:

      【解决方案2】:

      试试这个:

      Resources:
        MyApi:
          Type: AWS::Serverless::Api
          Properties:
            StageName: dev
            Cors:
              AllowOrigin: "'*'"
              AllowHeaders: "'*'"
            Auth:
              AddDefaultAuthorizerToCorsPreflight: False
              DefaultAuthorizer: MyLambdaTokenAuthorizer
              Authorizers:
                MyLambdaTokenAuthorizer:
                  FunctionArn: !GetAtt MyAuthFunction.Arn
      
        HelloFunction:
          Type: AWS::Serverless::Function
          Properties:
            Handler: functions/hello/handler.hello
            CodeUri: "."
            Events:
              HelloAPI:
                Type: Api
                Properties:
                  Path: /hello
                  Method: get
                  RestApiId: !Ref MyApi
              HelloAPIOptions:
                Type: Api
                Properties:
                  Path: /hello
                  Method: options
                  RestApiId: !Ref MyApi
      
      

      我更改了核心策略并为OPTIONS /hello 添加了一个端点。

      【讨论】:

        猜你喜欢
        • 2019-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-10
        • 1970-01-01
        相关资源
        最近更新 更多