You can make it works with a Middleware class. Let me give you an idea.
namespace MyAppHttpMiddleware;
use Closure;
use IlluminateSupportFacadesApp;
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 = [
'IlluminateFoundationHttpMiddlewareCheckForMaintenanceMode',
'IlluminateCookieMiddlewareEncryptCookies',
'IlluminateCookieMiddlewareAddQueuedCookiesToResponse',
'IlluminateSessionMiddlewareStartSession',
'IlluminateViewMiddlewareShareErrorsFromSession',
// appending custom middleware
'MyAppHttpMiddlewareHttpsProtocol'
];
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' => [
IlluminateCookieMiddlewareAddQueuedCookiesToResponse::class,
IlluminateSessionMiddlewareStartSession::class,
IlluminateViewMiddlewareShareErrorsFromSession::class,
// here
MyAppHttpMiddlewareHttpsProtocol::class
],
];
Remember that web
group is applied to every route by default, so you do not need to set web
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 with https://
once the website is rendered.