AWS API Gateway:不能同时使用CORS和API密钥身份验证吗?

问题描述

我正在使用AWS SAM创建一些由API-网关事件触发的Lambda函数

通常,它可以工作,但是我需要添加两个功能:CORS和API密钥身份验证。

我已经能够进行设置,因此需要API密钥才能调用该API。

这是我的Globals的{​​{1}}部分:

template.yaml

这很好用。

我还能够对其进行设置,使其支持CORS。

这是我的Globals: Api: Auth: ApiKeyrequired: true 中的Resources/Api部分:

template.yaml

但是,仅当我 一个或另一个执行时,它才有效。

换句话说,如果我同时

Resources:
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      Cors:
        AllowMethods: "'*'"
        AllowHeaders: "'*'"
        AllowOrigin: "'*'"
        AllowCredentials: "'*'"

...它停止工作。

具体来说,sam CLI工具可构建和部署sam应用程序;但是,如果我在浏览器中调用API,则请求将失败:

enter image description here

这是具体的错误消息:

Globals:
  Api:
    Auth:
      ApiKeyrequired: true
Resources:
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
      Cors:
        AllowMethods: "'*'"
        AllowHeaders: "'*'"
        AllowOrigin: "'*'"
        AllowCredentials: "'*'"

对为什么会这样以及如何解决它有任何见解,以便我可以同时支持CORS和API密钥身份验证?

解决方法

它在 ApiKeyRequired 为 true 且 CORS 开启时失败的原因是 ApiKeyRequired 正在向所有选项调用添加 api key required 属性,这会导致预检失败,因为在选项调用中包含身份验证详细信息不是标准的。

如果您尝试在 swagger/openapi 模板中定义所有集成,我没有解决方案来解决这个问题。

您可以通过使用 lambda 中的事件定义集成并指定哪些方法应该启用 api 密钥来解决此问题,然后从网关中删除 ApiKeyRequired。

在你的 lambda 上有

Events:
    HttpGet:
      Type: Api 
      Properties:
        Path: "/jobs"
        Method: GET
        RestApiId: !Ref ApiGateway
        Auth:
          ApiKeyRequired: True
,

AllowCredentials不会true吗?

,

您提到“如果我在浏览器中调用API” ,则会产生错误。

该错误源于浏览器实现的一种称为同源策略的安全机制。 See David Katz's Medium post.

Katz提供了有关错误,其原因和一些解决方案的更详细的信息。其中包括使用浏览器插件或代理服务器(您或他人的代理服务器)。