Laravel routes behind reverse proxy

I ran into the same (or similar problem), when a Laravel 5 application was not aware of being behind an SSL load-balancer.

I have the following design:

  • client talks to an SSL load balancer over HTTPS
  • SSL load balancer talks to a back-end server over HTTP

That, however, causes all the URLs in the HTML code to be generated with http:// schema.

The following is a quick'n'dirty workaround to make this work, including the schema (http vs. https):

Place the following code on top of app/Http/routes.php

In latest version of laravel, use web/routes.php

$proxy_url    = getenv('PROXY_URL');
$proxy_schema = getenv('PROXY_SCHEMA');

if (!empty($proxy_url)) {
   URL::forceRootUrl($proxy_url);
}

if (!empty($proxy_schema)) {
   URL::forceSchema($proxy_schema);
}

then add the following line into .env file:

PROXY_URL = http://igateway.somedomain.com

If you also need to change schema in the generated HTML code from http:// to https://, just add the following line as well:

PROXY_SCHEMA = https

In latest version of laravel forceSchema method name has changed to forceScheme and the code above should look like this:

if (!empty($proxy_schema)) {
    URL::forceScheme($proxy_schema);
}

Go to app/Http/Middleware/TrustProxies.php and change the protected variable $proxies like this:

protected $proxies = ['127.0.0.1'];

Just this! Be happy!


Because laravel route is created not from the config/app itself rather than from the server. My solution is adding the proxy_set_header Host to the nginx's config.

server {
    listen 80;
    server_name my.domain.com;

    location / {
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host  my.domain.com;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://127.0.0.1:8000;
    } 
}

i'm using laravel 8 with nginx docker inside a running nginx on the machine, so yeah it's double nginx


Ok, so I got it. Hopefully this will help someone in the future.

It seems like Laravel ignores the url property in the config\app.php file for http requests (it does state it's only for artisan), and it instead uses either HTTP_HOST or SERVER_NAME provided by apache to generate the domain for URLs.

To override this default url, go to your routes.php file and use the following method:

URL::forceRootUrl('http://subdomain.newurl.com');

This will then force the URL generator to use the new url instead of the HTTP_HOST or SERVER_NAME value.