Background:
I'm developing a Laravel 5.8 application running inside a Docker container on a server behind a reverse proxy, forwarding requests to the application based on a URL subdirectory, e.g. example.org/laravel/
.
Everything (Routes, HTTPS links, assets, ...) is working fine, except the redirect to the intended page after login.
I've accomplished proper URL generation for routes, assets, etc. by using
app('url')->forceRootUrl(config('app.url')); // https://example.org/laravel/
app('url')->forceScheme('https');
My Problem:
Suppose I have defined a route /foo
with the auth
middleware. When I'm logged out and visit example.org/laravel/foo
I am correctly redirected to example.org/laravel/login
, but after login I'm redirected to example.org/foo
, which does not exist.
Investigation results:
Accessing /foo
while being logged out
auth
middleware throws anAuthenticatedException
, which is caught inIlluminate\Routing\Pipeline
and passed toIlluminate\Foundation\Exceptions\Handler::unauthenticated()
(viaHandler::render()
)Handler::unauthenticated()
returnsredirect()->guest()
(Illuminate\Routing\Redirector::guest()
)Redirector::guest()
sets theurl.intended
session key to$this->generator->full()
(Illuminate\Http\Request::fullUrl()
viaIlluminate\Routing\UrlGenerator::full()
)Request::fullUrl()
callsSymfony\Component\HttpFoundation\Request::getUri()
(via$this->url()
)Request::getUri()
builds the URL from the$_SERVER
and request header data (see below) as follows ($qs
: query string):
$this->getScheme().'://'.$this->getHttpHost().$this->getBaseUrl().$this->getPathInfo().$qs
---
getScheme() => 'http' // As $_SERVER['HTTPS'] is not set
getHttpHost() => 'example.org' // From $this->headers->get('HOST')
getBaseUrl() => '' // From $_SERVER['SCRIPT_NAME'] *[1]
getPathInfo() => '//foo' // From $_SERVER['REQUEST_URI']
$qs => '' // From $_SERVER['QUERY_STRING']
---
*[1]: In Symfony\Component\HttpFoundation\Request::prepareBaseUrl():
$baseUrl = 'index.php' (L. 1745)
$requestUri = '//foo' (L. 1768)
$prefix = '/' (L. 1778)
=> return '' (L. 1780)
- This results in session
url.intended
being set tohttp://example.org//foo
instead ofhttp(s)://example.org/laravel/foo
$_SERVER
data (excerpt):
"HTTP_HOST" => "example.org"
"SERVER_NAME" => "example.org"
"QUERY_STRING" => ""
"REQUEST_URI" => "//foo"
"SCRIPT_NAME" => "/index.php"
Exact Composer package versions:
- laravel/framework: v5.8.3
- symfony/http-foundation: v4.2.4