Laravel и ngrok: URL-адрес домена не подходит для маршрутов и ресурсов - PullRequest
0 голосов
/ 06 мая 2018

Моя настройка:

  • Homestead на Mac OSX с несколькими настроенными сайтами
  • У меня есть один сайт, использующий domfit.test в качестве локального домена (автоматически сопоставляется с помощью hostsupdater)

Моя проблема:

Если я vagrant ssh, а затем share domfit.test, я получаю случайный сгенерированный URL-адрес ngrok, как и следовало ожидать (http://whatever.ngrok.io),, однако, когда я получаю доступ к этому URL, все мои ресурсы / маршруты имеют префикс http://domfit.test/ (http://domfit.test/login например)

Я пробовал следующее:

  • Установка APP_URL в качестве URL-адреса ngrok
  • 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_URL для ngrok:

Поиск по всей моей кодовой базе 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

Затем в моем контроллере я делаю это для простой отладки:

echo(url('/login'));
echo(route('login'));
echo($_SERVER['HTTP_HOST']);
echo($_SERVER['HTTP_X_ORIGINAL_HOST']);

Если я использую URL ngrok, то получаю вывод:

http://domfit.test/login
http://domfit.test/login
domfit.test
04b7beec.ngrok.io

Я не понимаю, как $_SERVER['HTTP_HOST'] возвращает неправильный URL?

Похоже, это может быть связано с этим: https://github.com/laravel/valet/issues/342

ДРУГОЕ РЕДАКТИРОВАНИЕ

Похоже, что это связано с командой share Homestead:

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

}

Который передает опцию -host-header на ngrok, которая согласно их документации:

Некоторые серверы приложений, такие как WAMP, MAMP и pow, используют заголовок Host для определения того, какой сайт разработки отображать. По этой причине ngrok может переписать ваши запросы с измененным заголовком Host. Используйте ключ -host-header для перезаписи входящих HTTP-запросов.

Если я использую ngrok без него, то отображаемый веб-сайт будет другим (потому что у меня есть несколько сайтов, настроенных в Homestead) - поэтому я все еще не уверен, как обойти это. В настоящее время я могу отключить другие сайты, поскольку я не активно их разрабатываю.

Ответы [ 3 ]

0 голосов
/ 02 февраля 2019

Несмотря на то, что вы переходите на URL-адрес ngrok, заголовок узла в запросе по-прежнему задается как имя вашего сайта. Laravel использует заголовок узла для создания абсолютного URL-адреса для ссылок, ресурсов и т. Д. Ngrok включает URL-адрес ngrok в заголовок X-Original-Host, но Laravel ничего об этом не знает.

Существует два основных решения проблемы:

  1. обновить запрос, указав правильные значения сервера и заголовка, или
  2. используйте метод forceRootUrl(), чтобы игнорировать значения сервера и заголовка.

доверенные прокси и переадресованный хост

Если вы используете TrustedProxies (по умолчанию в Laravel> = 5.5), и вы настроили его на доверие всем прокси (protected $proxies = '*';), вы можете установить заголовок X-Forwarded-Host на заголовок X-Original-Host. Laravel будет использовать значение в заголовке X-Forwarded-Host для построения всех абсолютных URL.

Вы можете сделать это на уровне веб-сервера. Например, если вы используете 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}]

Если вы предпочитаете обрабатывать это в своем приложении, а не на веб-сервере, вам нужно будет обновить запрос 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'));
    }
}

Не использует TrustedProxies

Если вы не используете TrustedProxies, вы не можете использовать метод .htaccess. Однако вы все равно можете обновить значения сервера и заголовков в вашем приложении. В этом случае вам потребуется перезаписать заголовок узла:

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'));
    }
}

Использование 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'));
    }
}
0 голосов
/ 01 апреля 2019

Вот что я придумала для своей проблемы <base> tag ngrok:

<base href="{{request()->isSecure() ? 'https' : 'http'}}://{{ $_SERVER['HTTP_X_ORIGINAL_HOST'] ?? request()->getHttpHost() }}">
0 голосов
/ 07 мая 2018

В файле app.config и .env попробуйте изменить его на:

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

...