Laravel和Ngrok:URL域对于路由和资产不正确

Dom*_*ams 7 laravel ngrok laravel-5 homestead vagrant-share

我的设置:

  • 在Mac OSX上配置了多个站点的Homestead
  • 我有一个使用domfit.test作为本地域的站点设置(使用hostsupdater自动映射)

我的问题:

如果I vagrant ssh,然后share domfit.test得到您所期望的随机生成的ngrok URL(http://whatever.ngrok.io),但是当我访问该URL时,我所有的资源/路由都以http://domfit.test/http:// domfit .test / login

我尝试了以下方法:

  • 将APP_URL设置为ngrok URL
  • php artisan config:clear
  • php artisan cache:clear
  • {{ url('login') }}
  • {{ route('login') }}

我的理解是url()应该返回浏览器请求的实际URL(而不是使用APP_URL),但始终返回domfit.test

如果我在我的重新命名的网站Homestead.yaml(例如到newdomfit.test),并重新规定,那么这是该域url()route()用途的,不管我的APP_URL。因此,Homestead.yaml似乎正在强迫该领域。哪个提出了问题-您实际上打算如何使用共享功能?

我是Laravel的新手,所以我不确定是否所有这些都是预期的行为,并且我误会了什么?

我只希望模板中的链接和资源可用于本地(domfit.test),共享(ngrok)以及最终使用同一段代码进行生产。我担心的是,当我尝试将该网站上线时,我将不得不更改所有我的信息route()url()参考。

在下面编辑

好的,我只是再试一次。更改APP_URLngrok

在我的整个代码库中搜索domfit.test,并且似乎只有一些随机会话文件具有引用:

代码/ domfit /存储/框架/会话/

APP_NAME=DomFit
APP_VERSION=0.01
APP_ENV=local
APP_KEY=XXXX
APP_DEBUG=true
APP_URL=http://04b7beec.ngrok.io
Run Code Online (Sandbox Code Playgroud)

然后,在我的控制器中,可以通过它进行一些简单的调试:

echo(url('/login'));
echo(route('login'));
echo($_SERVER['HTTP_HOST']);
echo($_SERVER['HTTP_X_ORIGINAL_HOST']);
Run Code Online (Sandbox Code Playgroud)

如果使用ngrokURL,则输出为:

http://domfit.test/login
http://domfit.test/login
domfit.test
04b7beec.ngrok.io
Run Code Online (Sandbox Code Playgroud)

我不明白如何$_SERVER['HTTP_HOST']返回错误的网址?

看起来可能与此有关:https : //github.com/laravel/valet/issues/342

另一个编辑

似乎与Homestead的share命令有关:

function share() {
if [[ "$1" ]]
then
    ngrok http ${@:2} -host-header="$1" 80
else
    echo "Error: missing required parameters."
    echo "Usage: "
    echo "  share domain"
    echo "Invocation with extra params passed directly to ngrok"
    echo "  share domain -region=eu -subdomain=test1234"
fi
Run Code Online (Sandbox Code Playgroud)

}

根据他们的文档,哪个选项传递-host-headerngrok哪个:

一些应用程序服务器(例如WAMP,MAMP和pow)使用Host标头确定要显示的开发站点。因此,ngrok可以使用修改后的Host标头重写您的请求。使用-host-header开关重写传入的HTTP请求。

如果我ngrok不使用它,那么显示的网站将是一个不同的网站(因为我在Homestead中配置了多个网站)-所以我仍然不确定如何解决这个问题。暂时我可以禁用其他站点,因为我没有积极开发这些站点。

pat*_*cus 9

即使您要转到ngrok网址,请求中的主机标头仍将设置为您的站点名称。Laravel使用主机头来构建链接,资产等的绝对URL。ngrok在X-Original-Host头中包含ngrok url ,但是Laravel对此一无所知。

该问题有两种基本解决方案:

  1. 使用正确的服务器和标头值更新请求,或者
  2. 使用该forceRootUrl()方法忽略服务器和标头值。

可信代理和转发主机

如果您使用的是TrustedProxies(Laravel> = 5.5中的默认值),并且已将其配置为信任所有代理(protected $proxies = '*';),则可以将X-Forwarded-Host标头设置为标X-Original-Host头。然后Laravel将使用X-Forwarded-Host标题中的值来构建所有绝对URL。

您可以在Web服务器级别执行此操作。例如,如果您使用的是apache,则可以将其添加到public/.htaccess文件中:

# Handle ngrok X-Original-Host Header
RewriteCond %{HTTP:X-Original-Host} \.ngrok\.io$ [NC]
RewriteRule .* - [E=HTTP_X_FORWARDED_HOST:%{HTTP:X-Original-Host}]
Run Code Online (Sandbox Code Playgroud)

如果您希望在应用程序而不是Web服务器中处理此问题,则需要更新Laravel请求。您可以选择很多地方来执行此操作,但是您的AppServiceProvider::boot()方法将是一个示例:

public function boot(\Illuminate\Http\Request $request)
{
    if ($request->server->has('HTTP_X_ORIGINAL_HOST')) {
        $request->server->set('HTTP_X_FORWARDED_HOST', $request->server->get('HTTP_X_ORIGINAL_HOST'));
        $request->headers->set('X_FORWARDED_HOST', $request->server->get('HTTP_X_ORIGINAL_HOST'));
    }
}
Run Code Online (Sandbox Code Playgroud)

不使用TrustedProxies

如果不使用TrustedProxies,则不能使用该.htaccess方法。但是,您仍然可以在应用程序中更新服务器和标头值。在这种情况下,您需要覆盖Host标头:

public function boot(\Illuminate\Http\Request $request)
{
    if ($request->server->has('HTTP_X_ORIGINAL_HOST')) {
        $request->server->set('HTTP_HOST', $request->server->get('HTTP_X_ORIGINAL_HOST'));
        $request->headers->set('HOST', $request->server->get('HTTP_X_ORIGINAL_HOST'));
    }
}
Run Code Online (Sandbox Code Playgroud)

使用 forceRootUrl()

如果您不想修改任何标头或Laravel请求,只需告诉URL生成器要使用的根URL。URL生成器具有一种forceRootUrl()方法,您可以用来告诉它使用特定值,而不用查看请求。同样,在您的AppServiceProvider::boot()方法中:

public function boot(\Illuminate\Http\Request $request)
{
    if ($request->server->has('HTTP_X_ORIGINAL_HOST')) {
        $this->app['url']->forceRootUrl($request->server->get('HTTP_X_FORWARDED_PROTO').'://'.$request->server->get('HTTP_X_ORIGINAL_HOST'));
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 -3

在您的 app.config 和 .env 文件中,尝试将其更改为:

'url' => env('APP_URL', ' http://localhost '),