Lumen PHP app URL routes revert to http scheme when hosted on Azure

2019-01-30

I've been playing around with the Polr app; deploying it to an Azure Linux app container with PHP enabled. One snag I hit was when browsing around the links shown in Polr to different pages, even when connecting to the app service's https:// URL, would revert back to a non-SSL link.

Lumen based PHP apps have a pattern of route management. For example, you can include a link in HTML by the following route reference:

<li class="visible-xs"><a href="{{ route('login') }}">Sign In</a></li>

Lumen's routing infrastructure looks at the current page request's protocol (http or https) and reuses that same protocol for the generated link.

The challenge is, when deploying to an Application Service in Azure, the PHP layer is told it is requested only as http, regardless if the browser's request is https or not. This is because Azure infrastructure terminates SSL at an outer layer, and the infrastructure executing the App Service code observes the request as non-SSL.

Fortunately, an HTTP header is injecting in to these requests by the outer layer, so PHP can observe the HTTP header and act accordingly. The HTTP header to look at is:

HTTP_X_FORWARDED_PROTO: https

In Lumen, we can override the current request's HTTPS flag, if the above header value is found, by adding an boot() method to a ServiceProvider:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    public function boot()
    {
        if($this->app['request']->server('HTTP_X_FORWARDED_PROTO') == 'https')
        {
            $this->app['request']->server->set('HTTPS', true);
        }
    }

}

I might add, I'm not an expert in the Lumen app framework, and the version of the framework I'm using is 5.2, so this approach may not be the ideal use of the framework's structure.

Polr's Lumen app bootstrap is contained in a file bootstrap/app.php, and a reference to the AppServiceProvider class above should be included in the following method:

$app->register(App\Providers\AppServiceProvider::class);