php - Laravel form doesn't return https url

I'm using Laravel Form along with https, but I'm having hard times with the Form component. For some reason Laravel always return http:// protocol for all the urls generated by the Form component.

This is my .env:

APP_NAME=Laravel
APP_ENV=local
APP_DEBUG=true
APP_URL=https://example.com

header.blade.php

{!! Form::open(['route' => 'boilerplate.logout', 'method' => 'post', 'id' => 'logout-form']) !!}
<button type="submit" class="btn nav-link d-flex align-items-center logout px-2" data-question="{{ __('boilerplate::layout.logoutconfirm') }}">
    <span class="fa fa-fw fa-power-off hidden-xs pr-1"></span>
</button>
{!! Form::close() !!}

routes/boilerplate.php

Route::post('logout', [LoginController::class, 'logout'])->name('logout');

The form should return:

<form method="POST" action="https://example.com/admin/logout" accept-charset="UTF-8" id="logout-form">

but I get:

<form method="POST" action="https://example.com/admin/logout" accept-charset="UTF-8" id="logout-form">

I found a similar question, and one user has proposed to add:

\URL::forceScheme('https');

within AppServiceProvider.php but, I would like to know why there is the following behavior. Is this an issue of the framework or am I doing something wrong?

Answer

Solution:

Because laravel doesn't care about the APP_URL for the scheme, laravel check if the https is support in the server, if you're in production server and the https has been implemented it will automatically use the https protocol

Laravel relay heavily at symfony http foundation in the URLGenerator.php that you can see if the $forceScheme is null it will fallback to $this->request->getScheme() which is instance of (symfony http foundation) Request.php

If you look the Request.php of symfony http foundation you can see methods (isSecure and getScheme)

public function isSecure()
{
    if ($this->isFromTrustedProxy() && $proto = $this->getTrustedValues(self::HEADER_X_FORWARDED_PROTO)) {
        return \in_array(strtolower($proto[0]), ['https', 'on', 'ssl', '1'], true);
    }

    $https = $this->server->get('HTTPS');

    return !empty($https) && 'off' !== strtolower($https);
}

public function getScheme()
{
    return $this->isSecure() ? 'https' : 'http';
}

as you can see that in isSecure method it check if the request is from trusted proxies or if the $_SERVER['HTTPS'] is on.

By setting URL::forceScheme('https'); it will force to be https and not used the $this->request->getScheme().

Source