How to get SpringBoot LiveReload Working over HTTPS

SpringBoot LiveReload is an essential tool for developers using Spring Boot Dev Tools. It automatically reloads your browser when you modify a front end source file in your Spring Boot application. This feature saves time and boosts productivity by making it quick and easy to view the changes you’ve made to the front-end.

Here’s how it works: Spring Boot enables a LiveReload server within the application, which listens on port 35729 by default. To connect to the LiveReload server over a WebSocket, you need to reference a JavaScript file from your pages. The server automatically triggers a page reload if the server resources have changed.

You can read more about setting up LiveReload and auto restart in my earlier post: SpringBoot DevTools Auto Restart and Live Reload.

To enable LiveReload in the development environment, you have added the following script tag to your front-end template:

<!-- Enable LiveReload in the dev environment --> <script th:if="${@environment.acceptsProfiles('dev','local')}" src="http://localhost:35729/livereload.js"></script>

The JavaScript file connects to a WebSocket on the same host and port, like ws://localhost:35729.

However, if you need to access your local development environment over HTTPS, LiveReload won’t work. You’ll encounter errors in your browser console regarding “not allowed to run insecure content” for the livereload.js reference. In other words, your browser refuses to load the JavaScript file over insecure HTTP when the page itself was served securely over HTTPS.

I haven’t found an easy way to get Safari to relax its security requirements. Nor to get Spring Boot to vend the LiveReload server over HTTPS. But I discovered a workaround using a tool called mitmproxy.

mitmproxy is a lightweight proxy server that supports HTTPS. It allows you to set up a port listening on localhost using HTTPS, which then proxies back to the LiveReload server on HTTP.

First you need to install mitmproxy. You can use the mitmproxy install instructions or if you’re on a Mac using brew, you can just run “brew install mitmproxy”.

What I’ve done it pick a new port for HTTPS traffic, in this case 35739, and will have mitmproxy proxy that back to 35729.

mitmproxy --mode reverse:http://localhost:35729 -p 35739

By default mitmproxy will use self signed SSL certificates. So you need to tell your browser to trust them before this will work. You can do this by opening https://localhost:35739/livereload.js in your browser. Then going through the steps to trust the server and certificate. You can also configure it to use real certificates if you prefer and avoid this step. Just follow these directions: mitmproxy certificates

Now, you need to update the script tag in your front end template to use port 35739 instead of 35729. You also need to change it from http to https, so the new tag will look like this:

<!-- Enable LiveReload in the dev environment -->
<script th:if="${@environment.acceptsProfiles('dev','local')}" src="https://localhost:35739/livereload.js"></script>

Now you’ll need to make one more change. By default the WebSocket connection is not encrypted, using ws:// instead of wss://. I haven’t figured out a way to reconfigure that. However you can tell your browser to automatically upgrade insecure requests to secure requests, which will include WebSockets.

Just add this meta tag to your front end template in the head:

<meta th:if="${@environment.acceptsProfiles('dev','local')}" http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

With those changes, you should be able to use LiveReload successfully using Spring Boot when developing on your local machine. Even when accessing the application over HTTPS either locally or through an ngrok tunnel.

Just remember you need to start the mitmproxy each time you want to develop with SpringBoot LiveReload.






Leave a Reply

Your email address will not be published. Required fields are marked *