Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel routes behind reverse proxy

Ok, so for development purposes, we have a dedicated web server. It's not currently connected directly to the internet, so I've setup an apache reverse proxy on another server, which forwards to the development server.

This way, I can get web access to the server.

The problem is, the routes in Laravel are now being prefixed with the internal server IP address, or the servers computer name.

For example, I go to http://subdomain.test.com but all the routes, generated using the route() helper, are displaying the following url: http://10.47.32.22 and not http://subdomain.test.com.

The reverse proxy is setup as such:

<VirtualHost *:80>
    ServerName igateway.somedomain.com

    ProxyRequests Off
    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>

    ProxyPass / http://10.47.32.22:80/
    ProxyPassReverse / http://10.47.32.22:80/
    <Location />
        Order allow,deny
        Allow from all
    </Location>
</VirtualHost>

I have set the actual domain name in config\app.php.

Question

How can I set the default URL to use in routing? I don't want it using the internal addresses, because that defeats the point of the reverse proxy.

I've tried enclosing all my routes in a Route::group(['domain' ... group, which doesn't work either.

like image 719
Phil Cross Avatar asked Apr 28 '15 07:04

Phil Cross


2 Answers

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);
}
like image 86
TimeLord Avatar answered Sep 21 '22 05:09

TimeLord


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.

like image 28
Phil Cross Avatar answered Sep 19 '22 05:09

Phil Cross