'Load Blade assets with https in Laravel

I am loading my css using this format: <link href="{{ asset('assets/mdi/css/materialdesignicons.min.css') }}" media="all" rel="stylesheet" type="text/css" /> and it loads fine for all http requests

But when I load my login page with SSL (https), I get a ...page... was loaded over HTTPS, but requested an insecure stylesheet 'http...

Can someone please tell me how do I make blade load assets over https instead of http?

Should I be trying to load the assets securely? Or is it not Blade's job?



Solution 1:[1]

I believe secure_asset is what you're looking for.

<link href="{{ secure_asset('assets/mdi/css/materialdesignicons.min.css') }}" media="all" rel="stylesheet" type="text/css" />

5/15/2018 Edit: While my answer addresses the question directly, it's a bit dated given what Laravel can do nowadays; there may be cases where you want to force HTTPS on certain environments but not on others.

See Scofield's answer below for a more flexible solution to cover for these kinds of cases.

08/11/2020 Edit: Seriously guys, Scofield's Answer is better than mine and will provide more flexibility for differing environments. Give him your updoots.

Solution 2:[2]

I use @Scofield answer by use \URL::forceScheme('https'); This solution also worked to show https for all routes but this not worked for me for $request->url() it show http instead of https

so I used $this->app['request']->server->set('HTTPS', true); instead of \URL::forceScheme('https');

I'm using Laravel 5.4 and update .env file and appserviceproviders

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;
use Log;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     *
     */
    public function boot()
    {
        If (env('APP_ENV') !== 'local') {
            $this->app['request']->server->set('HTTPS', true);
        }

        Schema::defaultStringLength(191);
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

in my env file I've changed

APP_ENV=local to APP_ENV=development

APP_ENV=local for localhost APP_ENV=development/production for on working server

after changing env run this artisan command

php artisan config:clear

Hope It helps :-)

Solution 3:[3]

There is a environment variable "ASSET_URL" where you put your app url with the http or https

ASSET_URL=https://your.app.url #for production

or

ASSET_URL=http://your.app.url #for local development

Solution 4:[4]

An another approach would be to pass true as the second parameter.

/**
 * Generate an asset path for the application.
 *
 * @param  string  $path
 * @param  bool    $secure
 * @return string
 */
function asset($path, $secure = null)
{
    return app('url')->asset($path, $secure);
}

As you see below secure_asset simply calls asset with the second parameter true.

/**
 * Generate an asset path for the application.
 *
 * @param  string  $path
 * @return string
 */
function secure_asset($path)
{
    return asset($path, true);
}

Solution 5:[5]

Figuring out if the current Request is secure or not should not be your decision. Underlying Symfony\Component\HttpFoundation\Request has isSecure method that Laravel uses internally.

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

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

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

So if your server is not passing the HTTPS header with On, it should be passing X-FORWARDED-PROTO and must be allowed by your TrustProxies middleware.

If you are behind reverse-proxy you should find out your proxy pass IP - you can do this easily by getting the $_SERVER['REMOTE_ADDR'] variable and setting the IP to your TrustProxies middleware:

/**
 * The trusted proxies for this application.
 *
 * @var array
 */
protected $proxies = [
    '123.123.123.123',
];

Laravel (Symfony) will then automatically detect if the Request is secure or not and choose the protocol accordingly.

Solution 6:[6]

The problem is cloudflare on my local machines is working fine but online server not solution is

 public function boot()
    {

        if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&  $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
             \URL::forceScheme('https');
        }
    }

Solution 7:[7]

Here is my configuration to make HTTPS working with assets. To enable this in production add REDIRECT_HTTPS=true in the .env file.

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        if(env('REDIRECT_HTTPS'))
        {
            \URL::forceScheme('https');
        }

        Schema::defaultStringLength(191);
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

Solution 8:[8]

I ended up putting this in my blade file:

@if(parse_url(url('/'), PHP_URL_SCHEME) == 'HTTPS')
    <link rel="stylesheet" href="{{ secure_asset('assets/css/slider.css') }}">
    <link rel="stylesheet" href="{{ secure_asset('assets/css/dropdown.css') }}">
@else
    <link rel="stylesheet" href="{{ asset('assets/css/slider.css') }}">
    <link rel="stylesheet" href="{{ asset('assets/css/dropdown.css') }}">
@endif

Solution 9:[9]

While upgrading Laravel version from 5.4 to 5.5, I had the same issue.

Just add \URL::forceScheme('https'); in app/Providers/AppServiceProvider.php. It worked.

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     *
     */
    public function boot()
    {
        \URL::forceScheme('https');
    }
...

Solution 10:[10]

Instead of "{{ asset('assets/mdi/css/materialdesignicons.min.css') }}" use "{{ secure_asset('assets/mdi/css/materialdesignicons.min.css') }}"

Solution 11:[11]

in .env file please change the value local to production

APP_ENV=production