Dynamically Configure reCaptcha Site Key

I’ve recently been working on a new web portal and ran into a problem of trying to figure out how to dynamically configure the reCaptcha site key.

It is a basic single page application (SPA) utilizing the Angular web framework (with component based development) written using Typescript (love it!) and decorated using Bootstrap CSS (can’t live without it!). The frontend Angular application is served up from the backend Java SpringBoot. application And, the whole thing is deploy in Docker containers to a Docker Swarm cluster.

Mind you, I have been a developer for longer than my esteemed colleague, who is working on the project with me, has even been alive. I have been a Java developer for over two decades. So, finally we have a component oriented and type safe web UI framework for developing HTML SPA applications that I actually like. Well, technically this stuff has been around for a few years; but 5 years ago working with Angular 1.4 was painful. My IntelliJ IDE has phenomenal IntelliSense for both Angular with Typescript and Java with Spring. So basically what I’m saying is that there is a new full-stack developer in town.

Google reCaptcha

There is one particular page we were concerned about ensuring that bot traffic is denied access as well as our REST API. This required us to integrate Google’s reCaptcha component and setup a reCaptcha site key and secret key thru their admin console.

recaptcha statistics from our development site
reCaptcha stats from our development site

After configuring the reCaptcha token we were able to test its capabilities and over time we gained insights thru its statistics.

Our Design

We generate a reCaptcha token on the web page and pass it along to the backend thru a REST call. The backend Java code calls Google again with the token, the site key, and the secret key and get’s back a number. This number is in the range of 0 to 1. Typically we see a 0.9 returned which is above the 0.5 threshold for determining whether it was a user or a bot that created this traffic.

web sequence diagram with Google reCaptcha
web sequence diagram with Google reCaptcha

The reCaptcha from Google uses both a site key and a secret key. The reCaptcha secret key is stored only on the backend. Whereas the site key is used on both the Angular web-app and the Java application. The Angular frontend calls Google with the reCaptcha site key to get the reCaptcha token. The backend Java code makes calls to Google with both the reCaptcha site key and secret key to get the reCaptcha number.

The Problem

We use Docker Secrets to store sensitive data like the reCaptcha secret key. We use Docker Configurations to store other configurable properties like the reCaptcha site key. And, we also had the reCaptcha site key embedded in an Angular provider in the app.modules.ts file. This was statically embedded. So the problem here is that our devops folks only want to maintain the reCaptcha site key in one place.

In the my mind this was a simple problem. We can definitely have a public facing REST service provide the reCaptcha site key. It’s already in the Angular code which is available to the world, so serving it in a REST call is no more insecure. However, the challenge began with the Angular configuration.

Remember how I told you the reCaptcha was configured using an Angular provider? The following code is a snippet of online documentation on how to configure reCatcha statically.

Using Angular provider to establish the reCaptcha Site Key
Using Angular provider to establish the reCaptcha Site Key

That’s all fine and dandy with a hard wired site key. But my devops folks do not like it. They want to maintain the reCaptcha site key on the backend, not in the frontend web app.

The Solution

Now I have to introduce a value provided from a dynamic REST call. As you can see below the fetch() method invokes the backend REST endpoint to obtain the reCaptcha site key.

Code snippet that dynamically configures the reCaptcha site key in the main.ts file
Code snippet that dynamically configures the reCaptcha site key in the main.ts file

Then the reCaptcha site key is used in the call to platformBrowserDynamic(). You can see how it is passed in as a provider in the form of a JSON array of configuration maps.

[{provide: RECAPTCHA_V3_SITE_KEY, useValue: siteKey}]

That bit of code is how I dynamically configure the reCaptcha site key, so I thought it might provide some insight for the next person. You can always get some additional help thru Capstone IT. Come check us out.

Mark Miller
Solutions Architect
Docker Accredited Consultant
(and Java/Angular developer!)