【问题标题】:401 return from an API Gateway Custom Authorizer is missing 'Access-Control-Allow-Origin' header来自 API Gateway 自定义授权方的 401 返回缺少“Access-Control-Allow-Origin”标头
【发布时间】:2016-08-23 03:08:27
【问题描述】:

为了防止未登录的用户通过AWS API Gateway调用我的lambda函数,我使用了Custom Authorizer lambda方案。

如果请求被授权 (200) 并且我从被调用的 lambda 得到响应,一切正常,我得到 Access-Control-Allow-Origin 标头。

但如果请求未获得授权,我会得到一个没有 Access-Control-Allow-Origin 标头的 401,因此阻止我读取响应的 401 状态并将用户重定向到登录页面。

我相信这是因为自定义自动化机制不知道请求需要使用 CORS。有谁知道这实际上是问题所在?您知道任何可能的解决方案吗?

【问题讨论】:

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


    【解决方案1】:

    为未经授权的响应添加响应标头“Access-Control-Allow-Origin”应该可以解决此问题

    • 选择 API
    • 选择网关响应
    • 选择未授权
    • 编辑响应标头并添加值为“*”的 Access-Control-Allow-Origin

    【讨论】:

      【解决方案2】:

      为了为我们的 SPA(我们使用 AWS Cognito 授权方)解决此问题,我们在 DEFAULT 4xxx 和 DEFAULT 5xxx 网关响应中添加了下一个响应标头:

      Access-Control-Allow-Origin '{url_of_your_front-end}'
      Access-Control-Allow-Headers '{url_of_your_front-end}'
      

      我们设置了 {url_of_your_front-end} 而不是 '*',因为浏览器不喜欢它:D

      另外,我们设置了Access-Control-Allow-Credentials 'true' 标头以使浏览器满意。

      Picture with all headers

      【讨论】:

      • 只添加 url_of_your_front-end 对我们不起作用,因为我们有一个微型前端应用程序,并且我们有多个基于供应商的前端版本,并且所有供应商都有不同的 URL
      【解决方案3】:

      如果您像我一样遇到 API Gateway V2 问题,特别是 HTTP API 问题 - ANY 方法似乎不适用于即插即用 CORS 产品。我必须为每个方法单独创建一个路由(很烦人,因为它们都调用相同的 lambda 函数,但是哦,好吧)。

      【讨论】:

        【解决方案4】:

        我很高兴地宣布新的网关响应功能允许您为不调用您的集成的请求自定义错误响应。这允许您确保包含 CORS 标头,即使在失败的身份验证请求中也是如此。

        在我们的documentation 中了解更多信息,其中包括一个 CORS 示例。

        【讨论】:

        • 截断的那个json需要去哪里?
        • 如果您正在使用 serverless.yaml,这就是您需要了解的 github.com/serverless/examples/blob/master/…
        • 如何从 lambda 函数本身返回 cors 标头,例如使用 callbcack 或 context.fail
        • 请注意,如果您没有在函数部分定义 events.http,那么您将收到无服务器错误。 The CloudFormation template is invalid: Template format error: Unresolved resource dependencies [ApiGatewayRestApi] in the Resources block of the template
        【解决方案5】:

        这对我有用(内联在 AWS::APIGateway: 定义中)

        Resources:
          MyApi:
            Type: AWS::Serverless::Api
            Properties:
              StageName: Dev
              GatewayResponses:
                UNAUTHORIZED:
                  StatusCode: 401
                  ResponseParameters:
                    Headers:
                      Access-Control-Allow-Origin: "'*'"
                ACCESS_DENIED:
                  StatusCode: 403
                  ResponseParameters:
                    Headers:
                      Access-Control-Allow-Origin: "'*'"
                DEFAULT_5XX:
                  StatusCode: 500
                  ResponseParameters:
                    Headers:
                      Access-Control-Allow-Origin: "'*'"
                RESOURCE_NOT_FOUND:
                  StatusCode: 404
                  ResponseParameters:
                    Headers:
                      Access-Control-Allow-Origin: "'*'"  
        

        可用的 GatewayResponses 命名为:

        DEFAULT_INTERNAL
        DEFAULT_4XX
        DEFAULT_5XX
        RESOURCE_NOT_FOUND
        UNAUTHORIZED
        ACCESS_DENIED
        AUTHORIZER_FAILURE
        AUTHORIZER_CONFIGURATION_ERROR
        MISSING_AUTHENTICATION_TOKEN
        INVALID_SIGNATURE
        EXPIRED_TOKEN
        INTEGRATION_FAILURE
        INTEGRATION_TIMEOUT
        API_CONFIGURATION_ERROR
        UNSUPPORTED_MEDIA_TYPE
        REQUEST_TOO_LARGE
        BAD_REQUEST_PARAMETERS
        BAD_REQUEST_BODY
        THROTTLED
        QUOTA_EXCEEDED
        INVALID_API_KEY
        WAF_FILTERED
        

        因此您可以为这些受控 AWS 响应指定响应自定义。

        【讨论】:

          【解决方案6】:

          除了上面的答案之外,如果您不使用 Cloudformation/SAM 模板,您可以使用这个 python 脚本为自己节省一些手动步骤:

          import boto3
          import sys
          
          if len(sys.argv) != 3:
              print("usage: python script.py <API_ID> <STAGE>")
              exit()
          
          client = boto3.client('apigateway')
          
          response = client.put_gateway_response(
              restApiId=sys.argv[1],
              responseType='UNAUTHORIZED',
              statusCode='401',
              responseParameters={
                  "gatewayresponse.header.Access-Control-Allow-Origin": "'*'",
                  "gatewayresponse.header.Access-Control-Allow-Headers": "'*'"
              }
          )
          response = client.create_deployment(
              restApiId=sys.argv[1],
              stageName=sys.argv[2])
          

          【讨论】:

            【解决方案7】:

            解决所有 4XX 错误(包括 401 错误)的最简单方法是转到“网关响应”,然后选择“默认 4XX”,然后添加标题“Access-Control-Allow-Origin”和值'*'。

            见截图:

            【讨论】:

            • 我们不能使用通配符('*'),因为我们需要发送一个厨师。你知道不使用通配符允许多个 Access-Control-Allow-Origin 的方法吗?
            【解决方案8】:

            因为我花了一段时间才弄清楚如何在 Cloud Formation 中将它们全部放在一起,这里有一个 sn-p 显示如何设置它。

            ...
                MyApi:
                  Type: "AWS::ApiGateway::MyApi"
                  Properties:
                    Description: My API
                    Name: "my-api"
                MyApiAuthorizer:
                  Type: "AWS::ApiGateway::Authorizer"
                  Properties:
                     Name: "my-api-authorizer"
                     IdentitySource: "method.request.header.Authorization"
                     ProviderARNs:
                       - !GetAtt MyUserPool.Arn
                     RestApiId: !Ref MyAApi
                     Type: COGNITO_USER_POOLS
                MyApiGatewayResponse:
                  Type: "AWS::ApiGateway::GatewayResponse"
                  Properties:
                    ResponseParameters:
                      "gatewayresponse.header.Access-Control-Allow-Origin": "'*'"
                      "gatewayresponse.header.Access-Control-Allow-Headers": "'*'"
                    ResponseType: UNAUTHORIZED
                    RestApiId: !Ref MyApi
                    StatusCode: "401"
            

            【讨论】:

            • 您以正确的方式指出我,但经过一些更改后,我将其放在 MyAPI.GateawyResponses 上并工作:资源:MyApi:类型:AWS::Serverless::Api 属性:StageName:Dev GatewayResponses :未经授权:StatusCode:401 ResponseParameters:标头:Access-Control-Allow-Origin:“'*'”
            【解决方案9】:

            是的,这是 API Gateway 自定义授权方的一个已知错误。谢谢让我们注意到这个。当我们部署修复程序时,团队将更新这篇文章。造成的不便,深表歉意。

            【讨论】:

            • 有什么更新吗?似乎还没有发送标头。
            • 在这里遇到同样的问题。更新会很棒
            • 是的,这仍然是一个问题,考虑到它已经存在了多久,这非常荒谬。像这样的事情使 API Gateway 无法投入生产,最糟糕的是,直到您在服务上投入大量资金后才会发现。
            • AWS 团队,我们能提供什么帮助?我们严重依赖自定义授权 lambda,这个问题在我们的用户中引起了很多烦恼和困惑。
            • 我也有这个问题。已经调试了一段时间了。
            猜你喜欢
            • 2019-02-07
            • 2018-03-28
            • 2021-07-15
            • 2015-01-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-05-13
            • 2020-02-26
            相关资源
            最近更新 更多