Integrating Google reCaptcha v3 into Angular app with ng-recaptcha

Fel picture Fel · Dec 25, 2019 · Viewed 14.1k times · Source

I'd like to protect a register page from automatic submitions, so I decided to try reCaptcha v3. It's an Angular application, and I'm using ng-recaptcha module for easier integration. I've set up a basic example on Stackblitz so you can test it online:

https://stackblitz.com/edit/angular-qk3jhr

I have a couple of doubts/problems:

  1. If I write my valid Google key into the app.module.ts file, when I press the submit button, the this.recaptchaV3Service.execute call does nothing. Is it because the app is not in the domain I stated when generating reCaptcha V3 keys? Also, if I write a wrong key, Google complains with the following error:

Error: Invalid site key or not loaded in api.js:

  1. Once I'd get the token, what do i do with it? I've read the ng-recaptcha documentation but I don't see anything about it. I mean, when I have the token, what do I need to do to check if it's valid and send the form?

Thanks in advance,

Answer

Fel picture Fel · Dec 30, 2019

Finally, I got some time to try some things and I managed to make it work. Basically, what I did is:

1 Generate a pair of keys for testing (setting 'localhost' in the domain).

2 In the client app, I've set up the ng-recaptcha module as explained in its page (https://www.npmjs.com/package/ng-recaptcha#recaptcha-v3-usage-see-in-action). Then, from the user registration component (which I want to protect), I run the following code when pressing the 'Submit' button:

public beforeSubmittingForm(): void {
    this.recaptchaV3Service.execute('registerSubmit').subscribe(
        (token) => {
            // 'this.user' contains the data of the user we want to create. Add the received token
            this.user.recaptchav3_token = token;    

            this.submitForm();  // This sends the user data to the backend
        },
        (error) => {
            this.errors = [ 'Error trying to verify request (reCaptcha v3)' ];
        });
}

3 In the backend, in the user registration route, I use the axios library (https://www.npmjs.com/package/axios) to make a POST request to the Google verify service with the received token:

try {
    var result = await axios.post("https://www.google.com/recaptcha/api/siteverify", {}, {
        params: {
            secret: recaptcha_api_key,  // Secret API key
            response: req.body.recaptchav3_token    // Received token from the frontend
        }
    });

    if(result.score < 0.5) {
        return res.status(403).json({ msg: 'Google Recaptcha error' });
    }
} catch(e) {
    return res.status(403).json({ msg: 'Error trying to verify the request' });
}
// Continue with the registration process...

Hope it helps, cheers!