【问题标题】:passing cloud front custom domain URL to lambda将云端自定义域 URL 传递给 lambda
【发布时间】:2019-04-19 08:21:56
【问题描述】:

我有一个自定义域 URL (my-custom-domain.com),并且 REST API 支持查询和路径参数。

https://my-custom-domain.com/hello

https://my-custom-domain.com?firstparam=abc&secondparam=def

调用的 lambda 必须返回响应,并将一些路径/查询参数附加到 json 正文中的自定义域 URL。基本上是其他可以访问的资源。

示例: https://my-custom-domain.com/hellofromlambda1123

https://my-custom-domain.com?firstparam=abc&secondparam=yourblogpage&pagenumber=30

一个理想的用例是分页,我必须提供上一个和下一个链接。如何将自定义域 URL 传递给我的 lambda。 我正在研究节点 js 8

在传统的 JAVA 编程中,我们可以通过 HttpServletRequest.getRequestURL() 来实现。 获取自定义域 URL 的方法是什么。我为 DefaultCacheBehavior 启用了标头。 lambda 事件中的主机提供 API 网关 URL。有没有办法在 lambda 中获取自定义域的映射?

我的自定义域的 Cloud Formation 模板如下所示

AWSTemplateFormatVersion: '2010-09-09'
Description: Custom domain template

Parameters:
  ServiceName:
    Description: Name of the Service
    Type: String
  DeploymentEnv:
    Default: dev
    Description: The environment this stack is being deployed to.
    Type: String
  CertificateId:
    Description: SSL Certificate Id
    Type: String
  DomainName:
    Description: Name of the custom domain
    Type: String
  HostedZoneId:
    Description: Id of the hosted zone
    Type: String

Resources:
  APIDistribution:
    Type: AWS::CloudFront::Distribution
    Properties:
      DistributionConfig:
        Origins:
        - DomainName:  
            Fn::ImportValue:
              !Sub "InvokeURL-${DeploymentEnv}"
          Id: !Sub 'Custom-Domain-${DeploymentEnv}'
          CustomOriginConfig:
            OriginProtocolPolicy: https-only
            OriginSSLProtocols: [TLSv1.2]
        Enabled: 'true'
        DefaultCacheBehavior:
          AllowedMethods:
          - DELETE
          - GET
          - HEAD
          - OPTIONS
          - PATCH
          - POST
          - PUT
          DefaultTTL: 0
          TargetOriginId: !Sub 'Custom-Domain-${DeploymentEnv}'
          ForwardedValues:
            QueryString: 'true'
            Cookies:
              Forward: none
            Headers:
              - 'Accept'
              - 'api-version'
              - 'Authorization'
          ViewerProtocolPolicy: https-only
        Aliases:
          - !Sub '${DomainName}'
        ViewerCertificate:
          AcmCertificateArn: !Sub '${CertificateId}'
          SslSupportMethod: sni-only
          MinimumProtocolVersion: TLSv1.2_2018
  APIDNSRecord:
    Type: AWS::Route53::RecordSet
    DependsOn: "APIDistribution"
    Properties:
      HostedZoneId: !Sub '${HostedZoneId}'
      Comment: DNS name for the custom distribution.
      Name: !Sub '${DomainName}'
      Type: A
      AliasTarget:
        DNSName: !GetAtt APIDistribution.DomainName
        HostedZoneId: Z2FDTNDATAQYW2
        EvaluateTargetHealth: false
Outputs:
  DomainName: 
    Value: !GetAtt APIDistribution.DomainName

【问题讨论】:

  • 所以这里的问题似乎是您正在创建自己的 CloudFront 分配,并将其源域名设置为 API 网关端点——并且,使用此配置,可以预期 API网关实际上并不知道自定义域名。虽然这是一种有效的配置,有时也是一种理想的配置,但您这样做是否有特定原因,而不是在 API Gateway 本身中配置自定义域名?最佳解决方案可能取决于您的推理。
  • 是的@Michael-sqlbot 让云前端知道的意图是,如果我们可能需要给定 API 网关的多个路由,我们将在自定义域本身中配置它。此外,我们希望使用模板文件来运行所有云形成以实现自动化。

标签: node.js aws-lambda aws-api-gateway amazon-cloudfront


【解决方案1】:

感谢 @thomasmichaelwallace 在 AWS 论坛上指向 my post,该论坛解释了一种使用 Lambda@Edge 原始请求触发器将原始请求 Host 标头注入备用请求标头的方法。这是一种解决方案,但需要 Lambda 触发器,因此会产生额外的开销和成本。该解决方案实际上是关于处理多个域名的 CloudFront 分配,但需要向后端应用程序发送单个 Host 标头,同时提醒应用程序另一个请求标头,我任意称为 X-Forwarded-Host。

还有其他选择。

如果 CloudFront 分配只处理一个传入主机名,您可以简单地配置一个静态 custom origin header。这些由 CloudFront 无条件地注入到请求中(如果原始请求者设置了这样的标头,则在注入配置的标头之前将其删除)。设置X-Forwarded-Host: api.example.com,它将被注入到所有请求中并在API网关上可见。

这是最简单的解决方案,根据问题中的内容,它应该可以工作。

但直观的解决方案不起作用 - 您不能简单地将 Host 标头列入白名单以转发到源,因为这不是 API Gateway 所期望的。

但是应该有一种方法可以让它期待那个标题。

以下内容基于一些准确、独立的观察结果,但我没有将它们全部一起测试。想法是这样的:

  • 使用区域 API 网关部署,而不是边缘优化。当您使用自己的 CloudFront 分配时,您无论如何都不需要边缘优化部署,因为这会通过冗余地通过 CloudFront 网络发送请求来增加延迟。它也不适用于此设置。
  • 将您的 API 配置为自定义域(针对您的公开域)
  • 将适当的证书附加到 API 网关,但是
  • 做,不将DNS指向API网关给你分配的区域域名;相反,
  • 使用分配的区域端点主机名作为 CloudFront 中的源域名
  • 将 Host 标头列入白名单以进行转发

这应该起作用,因为它将导致 API Gateway 期待原始的 Host 标头,以及当 Host 标头被列入转发白名单时 CloudFront 在后端处理 TLS 的方式.

【讨论】:

  • 感谢我使用自定义源头实现了它。
  • 哇,区域端点的解决方案非常聪明。有没有人试过这个并且可以确认这有效?
  • @MatthieuNapoli 谢谢,我不记得我是否尝试过,但我没有理由想到它为什么不起作用。当 CloudFront 看到 Host 标头被列入白名单时,它使用源域名建立连接,然后使用浏览器提供的 Host 标头值进行 TLS 协商,并将该值作为 Host 传递给源,而不是覆盖Host 以匹配原始域名,这是默认行为。
【解决方案2】:

当使用 API Gateway + Lambda 和 Lambda Proxy integration 时,lambda 接收到的事件包括 headers.Host 和 headers.X-Forwarded-Proto 键,它们可以连接起来以构建完整的请求 URL。

例如https://my-custom-domain.com/hellofromlambda1123

{
  "headers": {
    "Host": "my-custom-domain.com"
    "X-Forwarded-Proto": "https"
  }
}

【讨论】:

  • 您好,“HOST”属性具有 API 网关 URL。但我需要自定义域 URL。有没有办法使用 API Gateway URL 找到自定义域 URL?
  • 你检查了吗?我们使用基本路径映射来获取自定义域 url,Host 是正确的域...
  • 是的,我有 :) “主机”是 API 网关 URL。 AWS CloudFront 中生成的自定义域 URL 未进入“主机”:(
  • 您如何提供您的域-您是否使用 API 网关的 basePathMapping?
  • 我正在使用云形成模板。从我的 API Gateway lambda 导出调用 url,并将其映射到 AWS::CloudFront::Distribution 下的 cloudFront 的云形成模板下。在上面的问题中添加了模板。
猜你喜欢
  • 2017-01-19
  • 1970-01-01
  • 2020-12-05
  • 2022-12-21
  • 2020-09-26
  • 2018-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多