How to force Laravel Project to use HTTPS for all routes?
Asked Answered
C

20

116

I am working on a project that requires a secure connection.

I can set the route, uri, asset to use 'https' via:

Route::get('order/details/{id}', ['uses' => 'OrderController@details', 'as' => 'order.details', 'https']);

url($language.'/index', [], true)

asset('css/bootstrap.min.css', true)

But setting the parameters all the time seems tiring.

Is there a way to force all routes to generate HTTPS links?

Crucifix answered 6/3, 2016 at 12:54 Comment(0)
H
166

Place this in the AppServiceProvider in the boot() method

if($this->app->environment('production')) {
    \URL::forceScheme('https');
}
Hansen answered 13/8, 2018 at 9:22 Comment(7)
This is a good option, instead of updating any server file.Portland
Thanks it worked laravel 7 and 8 perfectly thanks againPatagonia
When I used this my email verifications no longer worked. When clicking the verification link, users would get a 403: Invalid SignatureVelour
@AmiteshBharti can you please help me look into this question? #72845402Irrespective
Performance-wise, does it have any effect? Since it will be executed for every single request to the website.Materiality
Thank you this is the best answer. in addition to this the user might use Illuminate\Support\Facades\URL;Poona
it worked laravel 10, thanksZwart
T
45

Here are several ways. Choose most convenient.

  1. Configure your web server to redirect all non-secure requests to https. Example of a nginx config:

    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name example.com www.example.com;
        return 301 https://example.com$request_uri;
    }
    
  2. Set your environment variable APP_URL using https:

    APP_URL=https://example.com
    
  3. Use helper secure_url() (Laravel5.6)

  4. Add following string to AppServiceProvider::boot() method (for version 5.4+):

    \Illuminate\Support\Facades\URL::forceScheme('https');
    

Update:

  1. Implicitly setting scheme for route group (Laravel5.6):

    Route::group(['scheme' => 'https'], function () {
        // Route::get(...)->name(...);
    });
    
Travis answered 4/6, 2018 at 13:54 Comment(3)
In my Laravel 5.7.26 5. somehow disabled the website, however 4. worked as charm :)Breault
I am hosting my site on HostGator and I went into the cPanel tools and modified my Laravel 5.7 code and performed number 4 and when I go to my site by just typing mysite.tech, I still get sent to the not secure verion of my site. If I implicitely type mysite.tech then it works. Any idea why 4 did not work?Tillietillinger
4. Resolved the issue for meColchicum
R
41

I used this at the end of the web.php or api.php file and it worked perfectly:

URL::forceScheme('https');
Robbins answered 26/7, 2018 at 18:41 Comment(5)
I have a hostgator account hosting my laravel app. If I put this in Routes/web.php, it doesn't re route my site to https and the ssl cert is on.Tillietillinger
Have you checked for a .htaccess file? You could force https redirection there too.Robbins
I have two htaccess files, one in my main app directory and the other in my public DIR. I added the code in the post below yours into my main app .htaccess file. Should I also add it in my public .htaccess?Tillietillinger
Yeah, I think that's the one is working. Cause that's the place of the index.php file. How does your url index page end? Anyway if that doesn't work for you, HostGator has an impressive support, you could comment their answer as well.Robbins
So that WORKED :D, the only thing now though is that when the site reidrects it adds "/public/" to the end of the url. Do you know how I can trim that off?Tillietillinger
S
37

You can set 'url' => 'https://youDomain.com' in config/app.php or you could use a middleware class Laravel 5 - redirect to HTTPS.

Silvery answered 6/3, 2016 at 13:8 Comment(5)
Middleware is the way to go. Setting the 'url' property didn't work for me (L 5.1).Kloman
this is still not satisfying. It only means that routes that lead to http will be forwarded to https routes but forwarding is detrimental to SEO rankingsMoulton
This should be set by APP_URL variable in .envSholapur
I have APIs in my project will this run APIs as it is?Blossomblot
Can someone help me look into this question please #72845402Irrespective
W
32

Using the following code in your .htaccess file automatically redirects visitors to the HTTPS version of your site:

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Wayzgoose answered 6/3, 2019 at 15:57 Comment(2)
for laravel it should in public folder ... this is worked for me and other solution here didnt work on my cpanel serverUnspoiled
FLAWLESS! This worked perfectly for me. Site uploaded to shared hosting on 18th MARCH, 2023. Laravel version 10.2.0.Woodham
A
27

Force Https in Laravel 7.x (2020)


"2020 Update? Url::forceScheme was acting funky for me, but this worked liked a dime."


  1. https code snippet.

    resolve(\Illuminate\Routing\UrlGenerator::class)->forceScheme('https');


  1. Add that snippet within any Service Provider Boot Method

  • 1: Open app/providers/RouteServiceProvider.php.
  • 2: Then add the https code snippet to the boot method.
    /**
     * Define your route model bindings, pattern filters, etc.
     *
     * @return void
     */
    public function boot()
    {
        resolve(\Illuminate\Routing\UrlGenerator::class)->forceScheme('https');

        parent::boot();
    }
  • 3: Lastly run php artisan route:clear && composer dumpautoload to clear Laravel's cached routes and cached Service Providers.
Agogue answered 31/5, 2020 at 5:28 Comment(4)
Did you still have to configure in .htaccess or this alone was enough?Jigsaw
THANKS! This is the only solution worked for me, I faced this issue only on AWS Elastic Beanstalk with load balancer. I think Laravel could not generate https toutes because the connection between the load balancer and the ec2 (ubunto server) is an http.Tenancy
@Jigsaw did not have to configure .htaccess at the time, that may have been because it was already configured properly.Agogue
@Tenancy Interesting, I was working on an AWS project at the time of this post as well! That being said - if I'm remembering properly - I used this https setup in local development. I'm not sure if the other implementations didn't work because we had some AWS things happening locally or if it's just an interesting coincidence. Either way, thanks for pointing out the AWS detail!Agogue
F
20

Add this to your .htaccess code

RewriteEngine On 
RewriteCond %{SERVER_PORT} 80 
RewriteRule ^(.*)$ https://www.yourdomain.com/$1 [R,L]

Replace www.yourdomain.com with your domain name. This will force all the urls of your domain to use https. Make sure you have https certificate installed and configured on your domain. If you do not see https in green as secure, press f12 on chrome and fix all the mixed errors in the console tab.

Hope this helps!

Fley answered 1/12, 2017 at 21:40 Comment(4)
This works! but adds index.php after domain name.Inestimable
I am getting index.php after domain name too other way?Miculek
Any solution to avoid adding index.php at the end? it is breaking my routesLetterpress
Anyone reading this, just replace 'RewriteEngine On' with the above code in your.htaccess fileAder
P
12

Add this before the class name of this file app\Providers\AppServiceProvider.php

use Illuminate\Support\Facades\URL;

Then paste this code inside the boot function of app\Providers\AppServiceProvider.php file

if (config('app.env') === 'production') {
    URL::forceScheme('https');
}
Paleoasiatic answered 13/9, 2021 at 7:9 Comment(2)
This helped me on Laravel 9.Prentiss
That's nice to hear :)Paleoasiatic
I
10

I would prefer forceScheme instead of doing it on a web server. So Laravel app should be responsible for it.

So right way is to add if statement inside boot function in your app/Providers/AppServiceProvider.php

    if (env('APP_ENV') === 'production') {
        \Illuminate\Support\Facades\URL::forceScheme('https');
    }

Tip: to prove that you have APP_ENV configured correctly. Go to your Linux server, type env

This was tested on Laravel 5, specifically 5.6.

Irma answered 19/4, 2020 at 23:44 Comment(2)
this worked for me inside the RouteServiceProvider, but not AppServiceProvider for some reason 🤔Astomatous
This worked for me too. the correct .env config for this is: APP_ENV=productionVaulted
D
9

For laravel 8, if you tried all of the above methods but got browser redirected you too many times error, please set proxies in TrustProxies middleware like the following:

App\Http\Middleware\TrustProxies.php

/**
  * The trusted proxies for this application.
  *
  * @var array|string|null
*/
protected $proxies = '*';
Disorder answered 28/7, 2021 at 3:25 Comment(0)
D
8
public function boot()
{
  if(config('app.debug')!=true) {
    \URL::forceScheme('https');
  }
}

in app/Providers/AppServiceProvider.php

Darrendarrey answered 17/9, 2019 at 18:36 Comment(1)
It is better to make condition based on environment (in this case non-local), not debug settings.Firecure
P
8

Here's another option, this works on laravel 8.*. I'm not sure of lower versions though:

Add the ASSET_URL variable to your .env file.

For example:

ASSET_URL=https://secure-domain.com

You can find more info here: Laravel Helpers

Hint: pay attention to the comments in the link above.

Periphrasis answered 16/10, 2021 at 7:6 Comment(1)
This worked this night!Elyse
T
6

I figured out how to do this in a load-balanced infrastructure.

You need to add in you Nginx config:

location ~ \.php$ {
            include snippets/fastcgi-php.conf;
    #       # With php-fpm (or other unix sockets):
            fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;

            add_header X-Forwarded-Proto https;
            add_header X-Forwarded-Port 443;
            add_header Ssl-Offloaded "1";
            add_header Access-Control-Allow-Origin "*";
            fastcgi_param  HTTPS "on";
            fastcgi_param  HTTP_X_FORWARDED_PROTO "https";
    }

The importer pieces are the add_headers and pastcgi_params, it works like a charm through an AWS load balancer.

Tabshey answered 21/5, 2021 at 13:48 Comment(3)
For some unknown reason, this is the only thing that worked for me. HTTPS "on" was the only thing I needed to add, although nginx includes a line like fastcgi_param HTTPS $https if_not_empty but it did not work as expected, so I had to manually add this and force backend to use HTTPS;Receive
Cheers! Solved the exact problem we were having on AWS load balancer.Drifter
HTTPS on turned out to be the only thing I needed. Instead of enforcing Laravel, this one is good and could perform better.Dahlia
P
5

In your .env file, just use

FORCE_HTTPS=true

This worked for me and you can also together set APP Url to https://your-site.com as an additional step

Portauprince answered 18/4, 2021 at 20:51 Comment(0)
A
3

try this - it will work in RouteServiceProvider file

    $url = \Request::url();
    $check = strstr($url,"http://");
    if($check)
    {
       $newUrl = str_replace("http","https",$url);
       header("Location:".$newUrl);

    }
Accoucheur answered 27/8, 2019 at 21:8 Comment(2)
Please provide some explanation as to what is going on here.Hahnke
need to call exit; after call headerDr
O
3

The better way to solute this issue is : -> go to public folder, ->edit .htaccess just add this code below :

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

-> and save. -> close and re-open browser.

Onomastics answered 22/6, 2021 at 13:10 Comment(0)
R
0

What about just using .htaccess file to achieve https redirect? This should be placed in project root (not in public folder). Your server needs to be configured to point at project root directory.

<IfModule mod_rewrite.c>
   RewriteEngine On
   # Force SSL
   RewriteCond %{HTTPS} !=on
   RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
   # Remove public folder form URL
   RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
Redintegration answered 4/1, 2022 at 15:47 Comment(1)
your vhost have to point public directory it self to do not expose website content in case of apache malfunctionOperable
T
0

I'm using Apache server, the most efficient I think just change the virtual host configuration. Change it like this

<VirtualHost *:80>
   ServerName www.yourdomain.com
   Redirect / https://www.yourdomain.com
</VirtualHost>

<VirtualHost _default_:443>
   ServerName www.yourdomain.com
   DocumentRoot /usr/local/apache2/htdocs
   SSLEngine On
# etc...
</VirtualHost>
Tapley answered 22/1, 2022 at 4:57 Comment(1)
it is not enough in my case (apache proxy -> php/nginx container with laravel 8.x), I have Letsencrypt certificate and virtualhost are ok, I should configure app/Http/Middleware/TrustProxies.php to add local IP proxy and it should be present in protected $middleware in app/Http/kernel.phpZwart
S
0

Use the function secure_url() from laravel 5.2

$url = secure_url('user/profile');

{{ secure_url('your-link') }} //instead url()

reference laravel secure_url() function

Stigma answered 31/3, 2022 at 21:49 Comment(0)
R
0

No need for long process: simply go to your config/admin.php and set this to yes. If it's not there, add it.

/*
|--------------------------------------------------------------------------
| Access via `https`
|--------------------------------------------------------------------------
|
| If your page is going to be accessed via https, set it to `true`.
|
*/
'https' => env('ADMIN_HTTPS', true),
Ramer answered 30/3 at 22:41 Comment(2)
(a) Does this affect all routes as the question asks, or is it just for the admin. (b) Why are you changing the default? Wouldn't it make more sense to change the ADMIN_HTTPS environment variable?Rand
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Mckibben

© 2022 - 2024 — McMap. All rights reserved.