CNAME 到 CloudFront:读取服务器端的实际浏览器 URL

CNAME 到 CloudFront:读取服务器端的实际浏览器 URL

我正在尝试读取服务器端(Node.js)的实际浏览器 URL,但获取的是 EC2 实例 URL。

我有一个设置,其中包含一个在具有 Cloudfront 发行版的 EC2 上运行的 Node.js 应用程序。

我的域名 example.com 指向 Cloudfront 发行版:

类型:CNAME 记录
主机:stg(指向子域上的暂存服务器)
值:xxxxxxxxxxxxxxxx.cloudfront.net

一切都很顺利,只有一个小问题。我的应用程序需要读取浏览器中的实际 URL,但请求对象中的所有内容都指向 EC2 实例 ec2-xx-xx-xxx-xxx.ap-southeast-2.compute.amazonaws.com。

例如console.log(req.host) // c2-xx-xx-xxx-xxx.ap-southeast-2.compute.amazonaws.com

这是我的 Nginx 设置:

upstream node {
  server 127.0.0.1:3000;
  keepalive 64;
}

server {
  listen 80 default_server;
  listen [::]:80 default_server;

  server_name example.com *.example.com;

  location / {
    proxy_pass $scheme://node$request_uri;
    proxy_redirect off;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Proto-Version $http2;
    proxy_set_header X-Forwarded-Host $host:$server_port;
    proxy_set_header Host $http_host;
    proxy_set_header domain https://stg.example.com; # Temp fix
  }
}

我已经在 Nginx 中硬编码了一个标头proxy_set_header domain https://stg.example.com;,我可以在应用程序级别读取它,但它似乎不太正确。

有没有更好的办法?

答案1

将标头添加Host到标头白名单中,以便在 CloudFront 缓存行为设置中转发到原始服务器。

默认情况下,CloudFront 会重写此标头。

Host

如果您未将 CloudFront 配置为根据标头值进行缓存时的行为... CloudFront 将值设置为与请求的对象关联的来源的域名。

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html#request-custom-headers-behavior

添加Host到白名单应该可以解决您的问题。

但它也会产生新的问题,具体取决于您如何配置源以及您如何/是否在后端使用 SSL。如果通过 SSL 访问源,则不能dzzzexample.cloudfront.net使用它从浏览器的地址栏访问您的分发,除非后端证书与配置的源域名匹配。这种行为改变是有原因的,而且这是 CloudFront 的正确行为,但可能超出了这个问题的范围。请参阅HTTP 502 状态代码错误网关在 CloudFront 开发人员指南中了解有关此情况的详细说明。

答案2

如果您访问http://stg.example.com/https://stg.example.com/,您的浏览器应该会准确显示该地址。您无需执行任何操作即可实现此目的。

如果您的浏览器将地址更改为c2-xx-xx-xxx-xxx.ap-southeast-2.compute.amazonaws.com,则存在导致该情况的活动重定向,您必须找到该重定向的配置位置并将其取消。

相关内容