You can make it works with a Middleware class. Let me give you an idea.
namespace MyApp\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\App;
class HttpsProtocol {
public function handle($request, Closure $next)
{
if (!$request->secure() && App::environment() === 'production') {
return redirect()->secure($request->getRequestUri());
}
return $next($request);
}
}
Then, apply this middleware to every request adding setting the rule at Kernel.php
file, like so:
protected $middleware = [
'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
'Illuminate\Cookie\Middleware\EncryptCookies',
'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
'Illuminate\Session\Middleware\StartSession',
'Illuminate\View\Middleware\ShareErrorsFromSession',
// appending custom middleware
'MyApp\Http\Middleware\HttpsProtocol'
];
At sample above, the middleware will redirect every request to https if:
- The current request comes with no secure protocol (http)
- If your environment is equals to
production
. So, just adjust the settings according to your preferences.
Cloudflare
I am using this code in production environment with a WildCard SSL and the code works correctly. If I remove && App::environment() === 'production'
and test it in localhost, the redirection also works. So, having or not a installed SSL is not the problem. Looks like you need to keep a very hard attention to your Cloudflare layer in order to get redirected to Https protocol.
Edit 23/03/2015
Thanks to @Adam Link
‘s suggestion: it is likely caused by the headers that Cloudflare is passing. CloudFlare likely hits your server via HTTP and passes a X-Forwarded-Proto header that declares it is forwarding a HTTPS request. You need add another line in your Middleware that say…
$request->setTrustedProxies( [ $request->getClientIp() ] );
…to trust the headers CloudFlare is sending. This will stop the redirect loop
Edit 27/09/2016 – Laravel v5.3
Just need to add the middleware class into web
group in kernel.php file
:
protected $middlewareGroups = [
'web' => [
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
// here
\MyApp\Http\Middleware\HttpsProtocol::class
],
];
Remember that
web
group is applied to every route by default, so you do not need to setweb
explicitly in routes nor controllers.
Edit 23/08/2018 – Laravel v5.7
- To redirect a request depending the environment you can use
App::environment() === 'production'
. For previous version was
env('APP_ENV') === 'production'
. - Using
\URL::forceScheme('https');
actually does not redirect. It just builds links withhttps://
once the website is rendered.