【发布时间】:2018-07-08 10:13:14
【问题描述】:
问题总结
假设您运行一个服务器并希望仅为使用用户名和密码登录的用户(经过身份验证的用户)提供来自 localhost 应用程序的内容。
应用程序在您的服务器上运行,但不向公众公开。它只能通过您服务器上的http://localhost:3838 获得。
为简单起见,假设这是您运行 localhost 应用程序的方式:
cd my-private-folder
python3 -m http.server 3838
经过身份验证的用户应该可以前往http://example.com/app查看 由 localhost 应用提供的内容。
应拒绝未经身份验证的用户访问并重定向到登录页面。
问题
Apache 有一个指令
ProxyPass在将请求发送到目标之前修改请求中的 HTTP 标头。它还有一个指令ProxyPassReverse,它会在响应返回给用户之前修改响应中的标头。有没有办法在 PHP 中模仿 Apache 的行为?
有没有使用Laravel PHP 框架的简单方法?
作为参考,有一个名为 oxy 的包在 Go 中实现了这个目标。我不知道 PHP 的等效包。
尝试 1 失败:使用路由
这是我在 Laravel 5.5 中尝试过的:
# /var/www/example.com/routes/web.php
Route::get('/app', function() {
return Response::make(
file_get_contents("http://localhost:3838/")
);
});
# This does not work, because the HTTP header is not modified.
Route::get('/app/{any}', function($any) {
return Response::make(
file_get_contents("http://localhost:3838/$any")
);
})->where('any', '.*');
这成功地将内容从localhost:3838 传递到example.com/app,但它未能传递应用程序请求的任何资源,因为HTTP 标头没有被修改。
例如:
localhost 应用使用 Javascript 请求
/resource.jpg我希望资源从http://localhost:3838/resource.jpg 传递到http://example.com/app/resource.jpg
相反,该应用发出失败的请求以获取 http://example.com/resource.jpg
要了解失败的原因,请参阅下面正确运行的 Apache 解决方案。 Apache 有一个名为 ProxyPassReverse 的指令修改 HTTP 标头,因此 localhost 应用程序从正确的 URL 请求资源。
使用 Apache
Apache 完美运行!但是,添加新用户需要在服务器上运行htpasswd 命令。
使用 Laravel,新用户应该可以在网站上自行注册。
没有 Laravel,你可以像这样使用 Apache 来保护应用程序:
# /etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>
ServerName example.com
Redirect /app /app/
ProxyPass /app/ http://localhost:3838/
ProxyPassReverse /app/ http://localhost:3838/
ProxyPreserveHost On
<Location /app/>
AuthType Basic
AuthName "Restricted Access - Please Authenticate"
AuthUserFile /etc/httpd/htpasswd.users
Require user myusername
# To add a new user: htpasswd /etc/httpd/htpasswd.users newuser
</Location>
</VirtualHost>
这个相关答案帮助我更好地理解 ProxyPassReverse 指令的工作原理:
【问题讨论】:
-
您能澄清一下“Laravel 不会重写 URL...”的意思吗?如果在
/app/{any}路由中输出dd("http://localhost:3838/$any");,你会看到什么? -
在
/app/{any}路由中我添加了dd("http://localhost:3838/$any");。当我访问http://example.com/app/shared时,我看到了"http://localhost:3838/shared" -
澄清一下,
localhost:3838已经开发好了,你只是想在 Laravel 中做一个代理? -
@Diogo 是的,完全正确。
-
@DiogoSgrillo 这只是问题的一个症状。应用程序 (
localhost:3838) 认为请求路径是localhost:3838,因此当它需要将资产返回为localhost:3838/app/resource.jpg时,它会返回该路径下的资产(例如:localhost:3838/resource.jpg),应用程序需要知道它在 @ 下运行987654353@.
标签: php laravel authentication proxy