简体   繁体   English

Cloudfront:转发主机 header 到 lambda function URL origin

[英]Cloudfront: Forward host header to lambda function URL origin

I have deployed the new Lambda function URL feature with a Cloudfront distribution to enable a custom domain.我已经部署了新的Lambda function URL功能和 Cloudfront 分发以启用自定义域。 However, my backend needs the real host head and not the one Cloudfront rewrites (see host here ), in this case to the function URL https://xxxxxxxx.lambda-url.eu-central-1.on.aws/ .但是,我的后端需要真正的主机头,而不是 Cloudfront 重写的主机头(请参阅此处的主机),在本例中为 function URL https://xxxxxxxx.lambda-url.eu-central-1.on.aws/

I also tried using the managed origin request policy AllViewer, but this neither works and in the browser it returns: "Message: null" and the x-cache header says cloudfront error.我还尝试使用托管源请求策略AllViewer,但这都不起作用,并且在浏览器中它返回:“消息:null”并且 x-cache header 表示云端错误。

My config currently looks like this:我的配置目前看起来像这样:

CloudFrontDistribution:
  Type: AWS::CloudFront::Distribution
  Properties:
    DistributionConfig:
      PriceClass: PriceClass_100
      HttpVersion: http2
      IPV6Enabled: true
      Comment: Distribution for Lambda Function URL
      Origins:
        # extract function url form your lambda resource
      - DomainName: !Select [2, !Split ["/", !GetAtt ApiLambdaFunctionUrl.FunctionUrl]]
        Id: LambdaOrigin
        CustomOriginConfig:
          HTTPSPort: 443
          OriginProtocolPolicy: https-only
      Enabled: 'true'
      DefaultCacheBehavior:
        TargetOriginId: LambdaOrigin
        # Disable caching as http api did not allow either
        CachePolicyId: '4135ea2d-6df8-44a3-9df3-4b5a84be39ad'
        ViewerProtocolPolicy: redirect-to-https
        SmoothStreaming: 'false'
        Compress: 'true'
      Aliases:
        - sub.domain.com
      ViewerCertificate:
        SslSupportMethod: sni-only
        MinimumProtocolVersion: TLSv1.2_2019
        AcmCertificateArn: xxxxx
FunctionRecordSetGroup:
  Type: AWS::Route53::RecordSetGroup
  DeletionPolicy: Delete
  DependsOn:
    - CloudFrontDistribution
  Properties:
    HostedZoneName: domain.com.
    RecordSets:
      - Name: sub.domain.com
        Type: A
        AliasTarget:
          # The following HosteZoneId is always used for alias records pointing to CF.
          HostedZoneId: Z2FDTNDATAQYW2
          DNSName: { 'Fn::GetAtt': [CloudFrontDistribution, DomainName] }

How can I achieve forwarding the host header?如何实现转发主机header?

The key is the host http header You need to use " https://xxxxxxxx.lambda-url.eu-central-1.on.aws/."关键是主机http header 你需要使用“ https://xxxxxxxx.lambda-url.eu-central-1.on.aws/”。 as host header otherwise will not work.作为主机 header 否则将无法工作。 Please check this anwser.请检查此答案。

https://stackoverflow.com/a/73364712 https://stackoverflow.com/a/73364712

I had the same issue with CloudFront when parsing the host header via the origin_request and origin_response Lambda@Edge functions since the header contains the value of the origin because that is the request's destination.在通过origin_requestorigin_response Lambda@Edge函数解析host header 时,我遇到了与 CloudFront 相同的问题,因为 header 包含origin的值,因为这是请求的目的地。 The request/response Lambdas are book-end functions that run before and after the call to the origin server.请求/响应 Lambda 是在调用源服务器之前和之后运行的书挡函数。

In the case of @peterhack (OP), the Lambda function URL is the origin without utilizing Lambda@Edge request/response interceptors, but the principle is the same.@peterhack (OP) 的案例中, Lambda function URL origin没有使用Lambda@Edge请求/响应拦截器的来源,但原理是相同的。

A CloudFront Function receives the correct host header because it receives the original viewer_request event. CloudFront Function接收到正确的主机 header,因为它接收到原始的viewer_request事件。 Since one cannot meaningfully overwrite the host header, I substituted a generic header viewer-host to receive the value:由于无法有意义地覆盖host header,我用一个通用的 header viewer-host来接收值:

// Cloudfront Function (ES5)
// viewer_request
function handler(event) {
    var request = event.request;

    request.headers["viewer-host"] = request.headers.host;

    return request;
}

Note : Here, we add the header to the request object and return the request object from the function so that CloudFront will continue onto the origin rather than immediately returning a response .注意:在这里,我们将 header 添加到request object 并从 function 返回request object,这样 CloudFront 将继续到origin ,而不是立即返回response

If you have trouble, AWS provides a similar example for modifying the request headers and includes links to more information.如果您遇到问题,AWS 提供了一个类似的修改请求标头的示例,并包含指向更多信息的链接。

Additionally, you will need to manually add the new header to the Origin Request Policy since AllViewer cannot be used for a Lambda origin because it forwards the wrong header as indicated by @carlos-garces in this thread.此外,您需要将新的 header 手动添加到源请求策略,因为AllViewer不能用于 Lambda origin ,因为它转发了错误的 header,如本线程中的@carlos-garces所示。


With the Cloudfront Function in place, modify your Lambda function to parse the new header. Cloudfront Function到位后,修改您的 Lambda function 以解析新的 header。

Lambda@Edge example: Lambda@Edge示例:

const hostHeader = event.Records[0].cf.request.headers['viewer-host'][0].value

Lambda origin URL example: Lambda origin URL 示例:

const hostHeader = event.headers['viewer-host']

One drawback is that your CloudFront Distribution will always run a CloudFront Function regardless of origin caching, and your desired origin Lambda will incur an additional Lambda invocation count, but only when reaching the origin .一个缺点是您的 CloudFront Distribution 将始终运行 CloudFront Function 而不管origin缓存,并且您想要的源 Lambda 将产生额外的 Lambda 调用计数,但仅在到达origin时。

With 2,000,000 free CloudFront Function invocations per month , there is a buffer until incurring an added cost.每月有 2,000,000 次免费 CloudFront Function 次调用,在产生额外成本之前有缓冲期。 Depending on your use case, it may fit within the free tier.根据您的用例,它可能属于免费套餐。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 CloudFront - 如何将所有请求标头转发到源 - CloudFront - How to forward all request headers to the origin 如何为 Cloudfront 创建 HttpOrigin 以使用 Lambda function url? - How do I create a HttpOrigin for Cloudfront to use a Lambda function url? 带主机标头转发的菊花链式 CloudFront - Daisy chained CloudFront with Host header forwarding 通过单个 lambda function 将s3中托管的文件内容解压到多个cloudfront url - Unzip file content hosted in s3 to multiple cloudfront url through a single lambda function 如何在 API 网关和云端访问 lambda 中的主机? - How to access host in lambda behind both API gateway and cloudfront? Terraform 中的可选 CloudFront Lambda 函数关联 - Optional CloudFront Lambda function association in Terraform CloudFront 未正确传回来自 S3 的 Access-Control-Allow-Origin 标头 - CloudFront is not correctly passing back the Access-Control-Allow-Origin header from S3 aws lambda 函数禁用和删除 python boto3 中的 CloudFront 分布 - aws lambda function to disable and delete CloudFront distribution in python boto3 Localhost 到 AWS Lambda 没有 'Access-Control-Allow-Origin' Header - Localhost to AWS Lambda No 'Access-Control-Allow-Origin' Header 将 Cloudfront 与 HTTP API 来源一起使用 - Using Cloudfront with an HTTP API Origin
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM