1

I've spent a ton of time trying to fix this but haven't had any luck so far. My app isn't loading css because of a mixed content error (The page at 'https://example.com/' was loaded over HTTPS, but requested an insecure stylesheet 'http://example.com/assets/css/magazine.min.css'. This request has been blocked; the content must be served over HTTPS). I know that I can load the assets by passing in true to the asset function but that would mean I would have to go to all the asset calls and change them. Is there a site wide setting I can configure so that it does https in production and http in local?

Thanks

2
  • As long as you're not using URL::forceScheme anywhere it should auto-detect based off the scheme of the request (and you're not passing anything in as the second parameter of asset()) Commented May 30, 2016 at 5:15
  • Is there a site wide setting I can configure so that it does https in production and http in local? - Uhm... middleware? Commented May 30, 2016 at 5:38

3 Answers 3

1

You can create something like ForceHttps middleware and than create condition for environment inside of it, like this:

public function handle($request, Closure $next)
{
    if (!\App::environment('local')) {
        \URL::forceSchema('https');
    }

    return $next($request);
}

Than add it to some route group or globally if you want.

NOTE: I would suggest to resolve this on your web server, not in Laravel

Sign up to request clarification or add additional context in comments.

2 Comments

I strongly advice using https on local environment too. It's important part of web development, so you should pay attention on local too. It's easy to miss something when you just test in live.
Question was explicit about this. Anyways, that can be little complicated to achieve in some local environments, but yes of course if there is a local self signed certificate feel free to remove the condition.
0

Just use asset() helper to generate asset's URL. It will use the current protocol.

Do NOT force assets to be loaded by https, unless they are sensitive (which is almost never the case). That would be an overhead, because you usually care more of safe website content than safe assets. In other words, if you accept loading http website, you most likely accept http assets. Instead, consider using middleware to redirect http to https on each non-safe request.

This is the middleware I'm using myself:

public function handle($request, Closure $next)
{
    if (!$request->secure()) {
        return redirect()->secure($request->getRequestUri());
    }

    return $next($request);
}

If you wish to use it, please remember to fire it BEFORE attaching any cookies, that is before Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse middleware.

2 Comments

You SHOULD force all content to be protected with HTTPS, otherwise, unprotected content (css, javascript, images) can be modified on-the-fly by a mitm attack for example and even CSS can be used as keylogger and compromise the protected content.
I didn't say we shouldn't protect the content. I said we shouldn't do it just for assets, because the most harmful modifications happen to HTML - that's the content after all. So it's good to serve entire website through HTTPS in this case and asset() helper will make assets' URLs https as well. If he doesn't use HTTPS for the website, he probably doesn't care about the security anyway, so I don't see why anyone would serve only CSS, JS or images by https. I hope I'm more clear now.
0

I created app/Helpers/SiteHelpers.php containing a function that overrides the default asset() function.

<?php

/**
 * Overrides the default asset() method, which generates an asset path for the application.
 *
 * @param  string $path
 * @param  bool   $secure
 *
 * @return string
 */
function asset ($path, $secure = null) {
    if (Request::server('HTTP_X_FORWARDED_PROTO') == 'https' || Request::server('HTTPS') == 'on') {
        $secure = TRUE;
    }

    return app('url')->asset($path, $secure);
}

then added it on bootstrap/autoload.php above require __DIR__.'/../vendor/autoload.php'; so it would look like below:

require __DIR__.'/../app/Helpers/SiteHelpers.php';
require __DIR__.'/../vendor/autoload.php';

this is flexible depending on whether you are serving your static content on http or https

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.