如何找到代理后面的应用程序基数 url?
How can I find an application's base url behind a proxy?
我们基于 PHP 的应用程序(定制,无框架)有时需要使用其基础完整 URL(例如将 URL 存储在发送给客户端的文件中)。例如基于 this question,我们的应用程序猜测这一点(这是基于比较 __FILE__
和 $SERVER
中的各种变量,如 SCRIPT_NAME
和 SERVER_NAME
)。
现在我们需要在我们的应用程序前面设置一个 (nginx) 反向代理。假设我们将 https://example.com/some/dir/onproxy/
映射到 http://backend/another/dir/onbackend/
.
有没有办法从 backend
上的代码猜测 public URL (https://example.com/some/dir/onproxy/
)?
AFAIU(根据我的阅读和实验),这是不可能的(HTTP_HOST
可能会给出 example.com
但我没有发现任何表明 some/dir/onproxy
的东西)但也许我遗漏了一些东西(一些变量或 nginx 配置选项)。
有什么想法吗?
万一不行,唯一的解决办法就是在配置中存储https://example.com/some/dir/onproxy/
,对吧?
编辑 1
按照@Progman 的建议,我尝试了 this question 上的解决方案。我已经尝试了接受的答案和第二个最受好评的答案,但是后端 URL 的 return(某些变体)(http://backend/another/dir/onbackend/
)。
编辑 2
我忘了说我想避免依赖 URL 在代理中重写。
由于 Nginx 在请求到达 PHP 后端之前更改请求,解决方案是以某种方式将原始请求数据添加到代理请求中。
一个常用的约定是将原始数据作为额外的 HTTP header 添加。请参阅 X_Forwarded_For 作为示例。
要将原始请求路径添加为新的 header,请向 Nginx 添加 proxy_set_header 指令。
location /some/dir/onproxy/ {
rewrite ^/some/dir/onproxy/(.*)$ /another/dir/onbackend/ break;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Request-URI $request; #** This adds the original path as a header **
proxy_set_header Host $http_host; # **Optional, will retain the original host name**
proxy_pass http://backend;
}
类似于您配置中的内容会将原始请求代理到后端的 PHP Web 服务器。它确实假定后端是 HTTP 服务器而不是 PHP-FPM.
在 PHP 中,获取单个 HTTP header 值的最快方法是通过 $_SERVER。原始请求路径将在 $_SERVER['HTTP_X_REQUEST_URI']
.
这只是一个示例,您可能需要测试和调试您的应用程序以完善解决方案。 php_info();是用于 PHP 环境的有用调试工具,但它对恶意行为者也很有用,因此请尽快从您的代码中删除或采取其他措施以确保它不会暴露。
我们基于 PHP 的应用程序(定制,无框架)有时需要使用其基础完整 URL(例如将 URL 存储在发送给客户端的文件中)。例如基于 this question,我们的应用程序猜测这一点(这是基于比较 __FILE__
和 $SERVER
中的各种变量,如 SCRIPT_NAME
和 SERVER_NAME
)。
现在我们需要在我们的应用程序前面设置一个 (nginx) 反向代理。假设我们将 https://example.com/some/dir/onproxy/
映射到 http://backend/another/dir/onbackend/
.
有没有办法从 backend
上的代码猜测 public URL (https://example.com/some/dir/onproxy/
)?
AFAIU(根据我的阅读和实验),这是不可能的(HTTP_HOST
可能会给出 example.com
但我没有发现任何表明 some/dir/onproxy
的东西)但也许我遗漏了一些东西(一些变量或 nginx 配置选项)。
有什么想法吗?
万一不行,唯一的解决办法就是在配置中存储https://example.com/some/dir/onproxy/
,对吧?
编辑 1
按照@Progman 的建议,我尝试了 this question 上的解决方案。我已经尝试了接受的答案和第二个最受好评的答案,但是后端 URL 的 return(某些变体)(http://backend/another/dir/onbackend/
)。
编辑 2
我忘了说我想避免依赖 URL 在代理中重写。
由于 Nginx 在请求到达 PHP 后端之前更改请求,解决方案是以某种方式将原始请求数据添加到代理请求中。
一个常用的约定是将原始数据作为额外的 HTTP header 添加。请参阅 X_Forwarded_For 作为示例。
要将原始请求路径添加为新的 header,请向 Nginx 添加 proxy_set_header 指令。
location /some/dir/onproxy/ {
rewrite ^/some/dir/onproxy/(.*)$ /another/dir/onbackend/ break;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Request-URI $request; #** This adds the original path as a header **
proxy_set_header Host $http_host; # **Optional, will retain the original host name**
proxy_pass http://backend;
}
类似于您配置中的内容会将原始请求代理到后端的 PHP Web 服务器。它确实假定后端是 HTTP 服务器而不是 PHP-FPM.
在 PHP 中,获取单个 HTTP header 值的最快方法是通过 $_SERVER。原始请求路径将在 $_SERVER['HTTP_X_REQUEST_URI']
.
这只是一个示例,您可能需要测试和调试您的应用程序以完善解决方案。 php_info();是用于 PHP 环境的有用调试工具,但它对恶意行为者也很有用,因此请尽快从您的代码中删除或采取其他措施以确保它不会暴露。