Simple implementation of reCAPTCHA 2 for use within Experience Cloud and Lightning Web Components. It's a child component which can be embedded into forms to enable reCAPTCHA validation before submission of a form.
It will also disable submit button until verified, and then also runs server-side validation as an extra layer of security.
Builder -> Settings -> Advanced -> Edit Head Markup -> Enter code as follows:
<!--reCaptcha v2 Checkbox-->
<script>
var grecaptchaReady = false;
var onloadCallback = function(){
grecaptchaReady = true;
};
var verifyCallback = function(token) {
document.dispatchEvent(new CustomEvent('grecaptchaVerified', {'detail': {response: token}}));
};
var expireCallback = function() {
document.dispatchEvent(new Event('grecaptchaExpired'));
};
var errorCallback = function() {
document.dispatchEvent(new Event('grecaptchaError'));
};
document.addEventListener('grecaptchaRender', function(e) {
onloadCallback = function() {
grecaptchaReady = true;
grecaptcha.enterprise.render(
e.detail.element,
{
'sitekey': e.detail.sitekey,
'callback': verifyCallback,
'expired-callback': expireCallback,
'error-callback': errorCallback,
'action': 'REGISTER'
}
);
};
if (grecaptchaReady) {
onloadCallback();
}
});
document.addEventListener('grecaptchaReset', function() {
grecaptcha.reset();
});
</script>
<script src='https://www.google.com/recaptcha/enterprise.js?render=explicit&onload=onloadCallback' async defer></script>
Note: If not using Enterprise keys, you can amend the code accordingly:
Change:
<script src='https://www.google.com/recaptcha/enterprise.js?render=explicit&onload=onloadCallback' async defer></script>
TO
<script src='https://www.google.com/recaptcha/api.js?render=explicit&onload=onloadCallback' async defer></script>
AND
grecaptcha.enterprise.render
TO
grecaptcha.render
Also, the action of 'REGISTER'
can be used to indicate which action the user is taking, or what form you are validating/submitting. Eg. LOGIN, REGISTER etc.
In addition, you need to add the Google URLs as trusted CSP sites:
- Builder -> Settings -> Security & Privacy
- Set Content Security Policy (CSP) Security Level to: Relaxed CSP: Permit Access to Inline Scripts and Allowed Hosts
- Added Trusted Sites for Scripts: https://www.google.com https://www.gstatic.com
You also need to add the Google reCAPTCHA Apex class to the Guest Profile for the Community:
Builder -> Settings -> General -> Configure access for guest or unauthenticated users (click link below) -> Add Apex Class GoogleRecaptchaController
The reCAPTCHA requires Enterprise API keys and the target community URL to be whitelisted in the Google reCAPTCHA Admin Console. However, non-Enterprise is supported by amending the HEAD markup above:
To enter the keys into Salesforce: Setup -> Custom Settings -> reCAPTCHA Keys -> Manage -> Edit -> Enter Site Key and Secret Key
To use the Google reCAPTCHA component, the parent form needs to be a LWC where effectively you import the google reCAPTCHA component and pass the form “submit” control over to the LWC component:
/* Example form */
<lightning-input type="email" value={email} label="Email"></<lightning-input>
/* reCAPTCHA component */
<c-google-recaptcha
submit-button-label="Sign Up"
onsubmit={handleSubmit}
>
</c-google-recaptcha>
Notes:
- As the Google reCAPTCHA component holds the Submit button, you can pass in a button label
- The parent form is still responsible for handling submit of the form, however the reCAPTCHA will only make this submit available after successfully verifying the user
handleSubmit(event) {
// submitForm is the Apex method for which you post your form data to
// the reCaptchaUniqueKey is important here as it's used as an additional
// server-side validation of the user that has verified against the reCAPTCHA
submitForm({
email: this.email,
reCaptchaUniqueKey: event.detail.uniqueKey
})...
@AuraEnabled
public static void submitForm(String email, String reCaptchaUniqueKey){
// This is important. It validates that the user who submitted the reCAPTCHA
// form is the same user who is now submitting the actual form. It's an effective
// server-side validation and without this security have proven the reCAPTCHA
// can be bypassed with a bot
if (!GoogleRecaptchaController.validateRecaptcha(reCaptchaUniqueKey)) {
throw new AuraHandledException('Could not validate reCAPTCHA key with server');
}
// Do rest of logic with submitted form data...
}