Skip to content

Commit

Permalink
Enhance the devtools live reload HTTP vs HTTPS port change to be conf…
Browse files Browse the repository at this point in the history
…iguration driven

Fixes #36
  • Loading branch information
devondragon committed Oct 31, 2023
1 parent 1933d1b commit 994a1c9
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 15 deletions.
30 changes: 20 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,29 +30,33 @@ The framework provides support for the following features:

## How To Get Started

### Configuring Your Local Environment
There is an example configuration file in /src/main/resources called application-local.yml-example. By default this project's gradle bootRun command runs Spring using the "local" profile. So you can just copy that file to application-local.yml and replace the values (keys, URLs, etc..) with your values. If you are using a different profile to run (such as default) you will just need to ensure the same configs are in place in your active configuration file(s).

Missing or incorrect configuration values will make this framework not work correctly.

### Database
This framework uses a database as a user store. By buildling on top of Spring JPA it is easy to use which ever datastore you like. The example configuration in application.yml is for a [MariaDB](https://mariadb.com) 10.5 database. You will need to create a user and a database and configure the database name, username, and password.

You can do this using docker with a command like this:

```
docker run -p 127.0.0.1:3306:3306 --name springuserframework -e MARIADB_ROOT_PASSWORD=springuserroot -e MARIADB_DATABASE=springuser -e MARIADB_USER=springuser -e MARIADB_PASSWORD=springuser -d mariadb:latest
```

Or on Apple Silicon:

```
docker run -p 127.0.0.1:3306:3306 --name springuserframework -e MARIADB_ROOT_PASSWORD=springuserroot -e MARIADB_DATABASE=springuser -e MARIADB_USER=springuser -e MARIADB_PASSWORD=springuser -d arm64v8/mariadb:latest

```

### Mail Sending (SMTP)
The framework sends emails for verficiation links, forgot password flow, etc... so you need to configure the outbound SMTP server and authentication information.

### SSO OAuth2 with Google and Facebook
The framework supports SSO OAuth2 with Google and Facebook. To enable this you need to configure the client id and secret for each provider.

For local development you will need a public hostname and HTTPS enabled. You can use ngrok to create a public hostname and tunnel to your local machine. You can then use the ngrok hostname in your Google and Facebook developer console configuration.

There is an example configuration file in /src/main/resources called application-local.yml-example. By default this project's gradle bootRun command runs Spring using the "local" profile. So you can just copy that file to application-local.yml and replace the values (keys, URLs, etc..) with your values. If you are using a different profile to run (such as default) you will just need to ensure the same configs are in place in your active configuration file(s).

Missing or incorrect configuration values will make this framework not work correctly.
For public OAuth you will need a public hostname and HTTPS enabled. You can use ngrok to create a public hostname and tunnel to your local machine. You can then use the ngrok hostname in your Google and Facebook developer console configuration.


### New Relic
Expand All @@ -77,17 +81,23 @@ Read the following articles:
- https://www.digitalsanctuary.com/java/how-to-get-springboot-livereload-working-over-https.html

### Live Reload over HTTPS Setup
If you are running your local dev env using HTTPS or referencing it from a ngrok tunnel using HTTPS, you will need to make a few changes to get Live Reload to work. First you need to comment out the LiveReload HTTP line near the bottom of the index.html Thymeleaf template file. And uncomment the HTTPS line just below.
If you are running your local dev env using HTTPS or referencing it from a ngrok tunnel using HTTPS, you will need to make a few changes to get Live Reload to work. First you need to tell the application to use HTTPS by setting the following properties in your application.yml file:

```
spring.devtools.livereload.https=true
```

You then need to install mitmproxy and configure it to intercept the HTTPS traffic. You can do this by running the following command:

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

By default, mitmproxy uses 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 and going through the steps to trust the server and certificate. Alternatively, you can configure mitmproxy to use real certificates and avoid this step. Follow these directions: https://docs.mitmproxy.org/stable/concepts-certificates/
By default, mitmproxy uses 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 and going through the steps to trust the server and certificate.

Alternatively, you can configure mitmproxy to use real certificates and avoid this step. Follow these directions: https://docs.mitmproxy.org/stable/concepts-certificates/

## Notes
Much of this is based on the [Baeldung course on Spring Security](https://www.baeldung.com/learn-spring-security-course). If you want to learn more about Spring Security or would like to add SSO integration or 2FA to your application, that guide is a great place to start.

The codebase provides examples of different ways to serve and consume APIs. For instance, some APIs return a 200 response for all queries with a success flag and use status codes to convey success or failures. Others only use the 200 response for successful requests and use 409 or 500 for various error scenarios. The AJAX client JavaScript in the codebase also showcases different approaches, with some triggering redirects to new pages while others display messaging directly on the current page. These examples aim to demonstrate different implementation options depending on your preferences and requirements.

Please note that there is no warranty or guarantee of functionality, quality, performance, or security made by the author. The code is available freely, but you assume all responsibility and liability for its usage in your application.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.digitalsanctuary.spring.user.util;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;

/**
* Provides a global advice for controllers to include LiveReload configuration details.
* <p>
* This advice will make the LiveReload port available to all controllers and views in the application. It is used on the layout.html template to
* include the LiveReload script in dev and local environments.
* </p>
*
* @author Devon Hillard
*/
@ControllerAdvice
public class LiveReloadGlobalControllerAdvice {

/**
* Flag to determine if the application is being accessed over HTTPS.
*/
@Value("${spring.devtools.livereload.https:false}")
private boolean isHttps;

/**
* Provides the appropriate LiveReload port based on the application's protocol.
* <p>
* If the application is running over HTTPS, the port will be {@code 35739}. Otherwise, it will be {@code 35729}.
* </p>
*
* @return The appropriate LiveReload port.
*/
@ModelAttribute("liveReloadPort")
public int liveReloadPort() {
return isHttps ? 35739 : 35729;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@
"name": "spring.security.oauth2.enabled",
"type": "java.lang.String",
"description": "A flag to enable/disable OAuth2 setup in WebSecurityConfig"
},
{
"name": "spring.devtools.livereload.https",
"type": "java.lang.String",
"description": "A description for 'spring.devtools.livereload.https'"
}
]
}
2 changes: 2 additions & 0 deletions src/main/resources/application-local.yml-example
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ spring:

livereload:
enabled: 'true'
https: 'true'

mvc:
log-request-details: 'true'
Expand Down Expand Up @@ -102,3 +103,4 @@ management:
export:
account-id: ACCTID
api-key: KEYYYYY

7 changes: 2 additions & 5 deletions src/main/resources/templates/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,8 @@ <h1>Static content for prototyping purposes only</h1>
<br /><br />
<div th:replace="~{fragments/footer :: footer}">Footer</div>

<!-- Enable LiveReload in the dev environment -->
<!-- Uncomment this line if you are running without HTTPS -->
<!-- <script th:if="${@environment.acceptsProfiles('dev','local')}" src="http://localhost:35729/livereload.js"></script> -->
<!-- Uncomment this line if you are running with HTTPS, and refer to my blog post here: https://www.digitalsanctuary.com/java/how-to-get-springboot-livereload-working-over-https.html -->
<script th:if="${@environment.acceptsProfiles('dev','local')}" src="https://localhost:35739/livereload.js"></script>
<!-- Enable LiveReload in the dev and local environments -->
<script th:if="${@environment.acceptsProfiles('dev','local')}" th:src="'https://localhost:' + ${liveReloadPort} + '/livereload.js'"></script>
</body>

</html>

0 comments on commit 994a1c9

Please sign in to comment.