Load Blade assets with https in Laravel

PhpLaravelHttpHttpsLaravel Blade

Php Problem Overview


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?

Php Solutions


Solution 1 - Php

I had a problem with asset function when it's loaded resources through HTTP protocol when the website was using HTTPS, which is caused the "Mixed content" problem.

To fix that you need to add \URL::forceScheme('https') into your AppServiceProvider file.

So mine looks like this (Laravel 5.4):

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

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

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

This is helpful when you need https only on server (config('app.env') === 'production') and not locally, so don't need to force asset function to use https.

Solution 2 - Php

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 3 - Php

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 4 - Php

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 5 - Php

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 6 - Php

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 7 - Php

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 8 - Php

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 9 - Php

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 10 - Php

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 11 - Php

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

Solution 12 - Php

in .env file please change the value local to production

APP_ENV=production

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionArtur GrigioView Question on Stackoverflow
Solution 1 - PhpScofieldView Answer on Stackoverflow
Solution 2 - Phpmaiorano84View Answer on Stackoverflow
Solution 3 - PhpAbdul RehmanView Answer on Stackoverflow
Solution 4 - PhpPaulo Gabriel Santana SilvaView Answer on Stackoverflow
Solution 5 - PhpOzan KurtView Answer on Stackoverflow
Solution 6 - PhpJan RichterView Answer on Stackoverflow
Solution 7 - PhpGoran SirievView Answer on Stackoverflow
Solution 8 - PhpChristiaan van SteenbergenView Answer on Stackoverflow
Solution 9 - PhpRikj000View Answer on Stackoverflow
Solution 10 - PhpElias MohammadiView Answer on Stackoverflow
Solution 11 - PhpDeveloper-FelixView Answer on Stackoverflow
Solution 12 - PhpAnjani BarnwalView Answer on Stackoverflow