Передача 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"
}
}