Mixed content (HTTPS / HTTP) errors with Inertia app

I deployed an Inertia.js & Laravel app but get a lot of Mixed content: load all resources via HTTPS to improve the security of your site errors:

Mixed Content: The page at 'https://[site].fly.dev/client/2/core-data' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://[site].fly.dev:8080/client/2/documents/'. This request has been blocked; the content must be served over HTTPS.

How can I force the request to port 8080 to be https?

In your fly.toml, add force_https=true to the relevant service (docs, example) and check if that helps?

Verify with curl --head http://myappname.fly.dev

Alternatively, you could add a HSTS header to responses from the web server (MDN).

Or, add a 301 permanent redirect from http://... to Location: https://... like how we do it.

Did you happen to use the fly launch command to have it generate the Dockerfile, etc for you?

Two things to care about with Laravel, and one question:

  1. Setup the TrustedProxy middleware trust any proxy
  2. Potentially you’ll also need to set your APP_URL environment variable in fly.toml
  3. Having a .env file is optional, in general I see more people just usingfly.toml’s environment variables or secrets. Are you using a .env file?

@fideloper-fly thanks for your answer & suggestions and help.

Did you happen to use the fly launch command to have it generate the Dockerfile , etc for you?

Yes.

  1. Setup the TrustedProxy middleware trust any proxy

$proxies in App\Http\Middleware\TrustProxies is set to *

  1. Potentially you’ll also need to set your APP_URL environment variable in fly.toml

Set, with https:// in fly.toml

  1. Having a .env file is optional, in general I see more people just usingfly.toml’s environment variables or secrets. Are you using a .env file?

I have one for local use, but set all the needed env vars in fly.toml and have .env in .dockerignore

However, the problem remains …

@ignoramous thanks for your answer!

In your fly.toml, add force_https=true to the relevant service (docs , example ) and check if that helps?

It was already in the default fly.toml:

  [[services.ports]]
    force_https = true
    handlers = ["http"]
    port = 80

  [[services.ports]]
    handlers = ["tls", "http"]
    port = 443

Verify with curl --head http://myappname.fly.dev

Seems to work.

curl --head http://myappname.fly.dev
HTTP/1.1 301 Moved Permanently
location: https://myappname.fly.dev/
server: Fly/54d1d920f (2022-09-30)
via: 1.1 fly.io
fly-request-id: 01GFG126HSX1WF8JCT1MP4D1A1-ams
date: Sun, 16 Oct 2022 09:12:40 GMT

Alternatively, you could add a HSTS header to responses from the web server (MDN).

Never heard of this header - will have to look into it.

Or, add a 301 permanent redirect from http://... to Location: https://... like how we do it.

But isn’t this already the case with force_https=true? Do I need to create & configure some certs manually?

1 Like

Do you know what helper is generating the url? Is it the route() helper method (Ziggy, under the hood IIRC) in the client side (within the JS) generating that URL that the ajax request is sent to?

I haven’t run into the “internal” (http + :8080) being generated before! :thinking:

I’m not familiar with Laravel and from this thread it seems like there’s more than one thing going on here…

I think you may have to add force_https=true to services section handling 8080:

 [[services.port]]
   force_https=true
   handlers=["http"]
   port=8080

Test would be curl --head http://myappname.fly.dev:8080/?

Re HSTS: don’t worry about it if you don’t use it. It is just one other way to hint browsers to switch to HTTPS.

No, I don’t use a helper to generate the urls - manual labor :slight_smile:

The same code runs on a VPS at the moment, standard nginx (provided by forge) configuration without any issues. So I guess it must has something to do with the proxy(ing) …

Yep, that definitely seems related to the proxy to me!

Laravel’s helper methods should get it right (url(), route(), asset(), and so on).

One possible idea is to set a BASE_URL based on (maybe!) url(“/“) and pass that to the front end to use.

@fideloper-fly passing the base url to the frontend could work.

However, at the moment I can’t even deploy (I guess I f***** something up when I played around out with ssh using wireguard) …

I have to put this aside for the moment, but will come back and test it. @ignoramous @fideloper-fly thanks for your time and the help so far!

2 Likes

@ignoramous @fideloper-fly half a year later and it just works - just wanted to let you know.

3 Likes

Hi!

This seems to be a Laravel issue. I solved by adding configs on Laravel.

In AppServiceProvider.php, add this code to public function boot() to force URLs to https when the app is running in production mode.

    /**
     * Bootstrap any application services.
     */
    public function boot(): void
    {
        if($this->app->environment('production')) {
            URL::forceScheme('https');
        };
    }

Check this: