Передача URL-адреса пользовательского домена с облачным фронтом в lambda

У меня есть пользовательский URL-адрес домена (my-custom-domain.com), а REST API поддерживает параметры запроса и пути.

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

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

Вызванная лямбда-функция должна возвращать ответ с некоторыми параметрами пути / запроса, добавленными к URL-адресу настраиваемого домена в теле json. В основном другие ресурсы, к которым можно получить доступ.

Пример: https://my-custom-domain.com/hellofromlambda1123

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

Идеальный вариант использования - это разбиение на страницы, где я должен дать предыдущую и следующую ссылки. Как передать пользовательский URL-адрес домена моей лямбде? Я работаю над узлом JS 8

В обычном JAVA-программировании мы можем достичь этого с помощью HttpServletRequest.getRequestURL(). Какой способ получить пользовательский URL домена. Я включил заголовки для DefaultCacheBehavior. Хост в лямбда-событии дает URL-адрес шлюза API. Есть ли способ получить сопоставление пользовательского домена внутри лямбды?

Шаблон My 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

2 ответа

Решение

Спасибо @thomasmichaelwallace за указание на мое сообщение на форуме AWS, в котором объясняется, как внедрить исходный запрос Host заголовок в альтернативный заголовок запроса, используя триггер Lambda@Edge Origin. Это одно из решений, но для него требуется лямбда-триггер, поэтому существуют дополнительные издержки и затраты. Это решение было на самом деле о распределении CloudFront, которое обрабатывает несколько доменных имен, но необходимо отправить одно Host заголовок к внутреннему приложению, одновременно предупреждая приложение о другом заголовке запроса, который я произвольно назвал X-Forwarded-Host,

Есть альтернативы.

Если дистрибутив CloudFront обрабатывает только одно входящее имя хоста, вы можете просто настроить статический пользовательский заголовок источника. Они безоговорочно вводятся в запросы CloudFront (и если исходный запросчик устанавливает такой заголовок, он отбрасывается до того, как настроенный заголовок будет введен). Задавать X-Forwarded-Host: api.example.com и он будет введен во все запросы и видим на API Gateway.

Это самое простое решение, и, исходя из того, что в вопросе, оно должно работать.

Но интуитивное решение не работает - вы не можете просто внести в белый список Host заголовок для пересылки к источнику, потому что это не то, что ожидает API-шлюз.

Но должен быть способ заставить его ожидать этот заголовок.

Следующее основано на ряде наблюдений, которые являются точными, независимо, но я не проверял их все вместе. Вот идея:

  • используйте развертывание Регионального API-шлюза, а не Оптимизированный для края. В любом случае вам не нужно развертывание, оптимизированное по краям, когда вы используете свой собственный дистрибутив CloudFront, потому что это увеличивает задержку, отправляя запрос через сеть CloudFront с избыточностью. Это также не будет работать в этой настройке.
  • настройте свой API как собственный домен (для вашего открытого домена)
  • присоединение соответствующего сертификата к API-шлюзу, но
  • не указывайте DNS на назначенное региональное имя домена, которое дает вам API Gateway; вместо,
  • используйте назначенное региональное имя хоста конечной точки в качестве исходного доменного имени в CloudFront
  • белый список заголовков для пересылки

Это должно работать, потому что это приведет к тому, что API-шлюз будет ожидать оригинального Host заголовок, в сочетании с тем, как CloudFront обрабатывает TLS на серверной части, когда Host заголовок внесен в белый список для пересылки.

При использовании API Gateway + Lambda с интеграцией Lambda Proxy событие, которое получает lambda, включает в себя headers.Host а также headers.X-Forwarded-Proto ключи, которые можно объединить для создания полного URL-адреса запроса.

Например для https://my-custom-domain.com/hellofromlambda1123

{
  "headers": {
    "Host": "my-custom-domain.com"
    "X-Forwarded-Proto": "https"
  }
}
Другие вопросы по тегам