Working on my first Laravel 5 project and not sure where or how to place logic to force HTTPS on my app. The clincher here is that there are many domains pointing to the app and only two out of three use SSL (the third is a fallback domain, long story). So I'd like to handle this in my app's logic rather than .htaccess.
In Laravel 4.2 I accomplished the redirect with this code, located in filters.php
:
App::before(function($request)
{
if( ! Request::secure())
{
return Redirect::secure(Request::path());
}
});
I'm thinking Middleware is where something like this should be implemented but I cannot quite figure this out using it.
Thanks!
UPDATE
If you are using Cloudflare like I am, this is accomplished by adding a new Page Rule in your control panel.
The answers above didn't work for me, but it appears that Deniz Turan rewrote the .htaccess in a way that works with Heroku's load balancer here: https://www.jcore.com/2017/01/29/force-https-on-heroku-using-htaccess/
I'm adding this alternative as I suffered a lot with this issue. I tried all different ways and nothing worked. So, I came up with a workaround for it. It might not be the best solution but it does work -
production <- It should be replaced with the APP_ENV value in your .env file
The easiest way would be at the application level. In the file
add the following:
and in the boot() method add the following:
This should redirect all request to https at the application level.
( Note: this has been tested with laravel 5.5 LTS )
For Laravel 5.6, I had to change condition a little to make it work.
from:
To:
This is for Larave 5.2.x and greater. If you want to have an option to serve some content over HTTPS and others over HTTP here is a solution that worked for me. You may wonder, why would someone want to serve only some content over HTTPS? Why not serve everything over HTTPS?
Although, it's totally fine to serve the whole site over HTTPS, severing everything over HTTPS has an additional overhead on your server. Remember encryption doesn't come cheap. The slight overhead also has an impact on your app response time. You could argue that commodity hardware is cheap and the impact is negligible but I digress :) I don't like the idea of serving marketing content big pages with images etc over https. So here it goes. It's similar to what others have suggest above using middleware but it's a full solution that allows you to toggle back and forth between HTTP/HTTPS.
First create a middleware.
This is what your middleware should look like.
Note that I'm not filtering based on environment because I have HTTPS setup for both local dev and production so there is not need to.
Add the following to your routeMiddleware \App\Http\Kernel.php so that you can pick and choose which route group should force SSL.
Next, I'd like to secure two basic groups login/signup etc and everything else behind Auth middleware.
Confirm that your middlewares are applied to your routes properly from console.
Now you have secured all the forms or sensitive areas of your application, the key now is to use your view template to define your secure and public (non https) links.
Based on the example above you would render your secure links as follows -
Non secure links can be rendered as
What this does is renders a fully qualified URL such as https://yourhost/login and http://yourhost/aboutus
If you were not render fully qualified URL with http and use a relative link url('/aboutus') then https would persists after a user visits a secure site.
Hope this helps!
You can make it works with a Middleware class. Let me give you an idea.
Then, apply this middleware to every request adding setting the rule at
Kernel.php
file, like so:At sample above, the middleware will redirect every request to https if:
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......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 inkernel.php file
:Edit 23/08/2018 - Laravel v5.7
App::environment() === 'production'
. For previous version wasenv('APP_ENV') === 'production'
.\URL::forceScheme('https');
actually does not redirect. It just builds links withhttps://
once the website is rendered.