Implement Google ReCaptcha Enterprise with score-based approach in Laravel

What is Google’s ReCaptcha Enterprise?
ReCaptcha Enterprise is built on the existing reCAPTCHA API and it uses advanced risk analysis techniques to distinguish between humans and bots. It include website protection from spam and abuse and detect other types of fraudulent activities on the sites such as credential stuffing, account takeover (ATO) and automated account creation.
ReCaptcha Enterprise offers more features and new enhancement in term of detection with more granular scores, reason codes for risky events, mobile app SDKs, password breach/leak detection, Multi-factor authentication (MFA), and the ability to tune your site-specific model to protect enterprise businesses.
For features comparison between normal reCaptcha and reCaptcha Enterprise, you may visit this link
How score-based work
This ReCaptcha Enterprise works basically the same as ReCaptcha V3 which without user interaction and only based on score but more security enhancement. In short, this score-based reCaptcha lets you understand the level of risk that the interaction poses and helps you to take appropriate actions for your site or application. You may refer this diagram for further understanding.
Implement in Laravel
Well, in this experiment we will try to add Google ReCaptcha Enterprise to a login form without using any package. I will show how to implement reCaptcha Enterprise without any user interaction, only based on score.
Here are the steps:
- Enable ReCaptcha API
- Create new reCaptcha Enterprise Key
- Create new Credential API Key
- Add keys to config file
- Implement reCaptcha scripting at Login page
- Create a Laravel Rule
- Add Validation rule to Login logic
- Testing and validation
Lets get started
Enable ReCaptcha API
For this step, i assume you already have google account. Go to this page and if you don’t have any project created yet, there will be a popup like below.

Above page showing if you are the first time visit the google cloud console. You may follow the process.

At the top of the page, you will see the search box. Search “Recaptcha Enterprise”.

You will be redirect to this page. If you don’t have any project created yet, google will ask you to create it first. Click on the “Create Project” to proceed.

Fill in the form. Just ignore the warning sign and click “Create”.

You will be redirect to https://console.cloud.google.com/apis/library/recaptchaenterprise.googleapis.com. In order to use reCaptcha Enterprise, you need to enable the API. Just click the Enable button and wait until it finish.
Please read the Pricing if you consider using as business purpose.

You will redirect to https://console.cloud.google.com/security/recaptcha after complete enable. If not, just search again at the search bar. You will see you need to enable billing. Don’t worry because google will only charge you if the API usage exceed 1Million assessment per month.
Create new reCaptcha Enterprise Key
Now we can proceed to create the reCaptcha Key.

Click on the “+Create Key” at the top of the enterprise keys table

You can put any label you desired as long as you remember. For the domains, if you are developing in the localhost, put “localhost” or “127.0.0.1”. You will see 4 options there. We can ignore all the options. For testing purpose, you may disable domain verification to ease your testing. Click “Create Key” to proceed.

You will be showing page of how you can integrate in your website. We can ignore first and proceed to next step
Create new Credential API Key
For the ReCaptcha Enterprise, you are required to use API Key instead of Secret key (deprecated).

Go to APIs & Services and click Credentials.

Click create credentials and choose API key.

Google will create a key directly and you must configure it after that. Click on Edit API Key.

You may rename the label if you want. Optionally, you can restrict the API usage only for reCaptcha Enterprise purpose (Recommended). The others restrictions is depends on your requirement. Click Save and we good to proceed to the next step.
Add keys to config file
Now, in order to use reCaptcha Enterprise, we need
- Project ID
- API Key
- Site Key
All of them we already created it in the previous steps except the project ID.

The project ID can be retrieve when you click your project name at the top of the console page. Now, go ahead to your .env file and fill the values to the correct keys.
GOOGLE_RECAPTCHA_PROJECT_ID=XXXX
GOOGLE_RECAPTCHA_API_KEY=XXXX
GOOGLE_RECAPTCHA_SITE_KEY=XXXX
After that, find a config file name services.php and add new lines with below code
<?php return [
...
'recaptcha_ent' => [
'project_id' => env('GOOGLE_RECAPTCHA_PROJECT_ID'),
'api_key' => env('GOOGLE_RECAPTCHA_API_KEY'),
'site_key' => env('GOOGLE_RECAPTCHA_SITE_KEY'),
],
]
Implement reCaptcha scripting at Login page
Now, we need a hidden input to put value after we get the token from the callback function. Unlike Checkbox challenge, it already render together. You can simply add a section in your form with below code
<input type="hidden" name="g-recaptcha-response" id="hidden-token"/>
<input type="hidden" name="g-recaptcha-action" id="hidden-action"/>
and alter your submit button with this
<button data-sitekey="{{ config('services.recaptcha_ent.site_key') }}"
data-callback='onSubmit'
data-action='login'
class="g-recaptcha">
Log In
</button>Then, put below javascript at the bottom of the page or any desire place
<script src="https://www.google.com/recaptcha/enterprise.js?render={{ config('services.recaptcha_ent.site_key') }}"></script>
<script>
function onSubmit(token) {
document.getElementById('hidden-token').value = token;
document.getElementById('hidden-action').value = "login";
document.getElementById("login-form").submit();
}
</script>Notice that, we also submit the action of the request. It is because the verification API parameter need those action.
Based on the script, it will automatically render once you click the submit button. If you want to customize, you may refer here.
Here is the sample login page i made based on Laravel Jetstream and Fortify
If you have successfully place the script, it should display a floating badge like this

It is quite annoying to show the badge floating in the page. We can easily hide it with a CSS
.grecaptcha-badge { visibility: hidden; }And the badge are gone. But there is condition where Google mention that in here
You are allowed to hide the badge as long as you include the reCAPTCHA branding visibly in the user flow
So basically you should always have such legal information legally checked before doing anything.
Now, Lets say we dump the request, we should see g-recaptcha-response appended along with form input.

Now, we can proceed to validate the token which is valid or not.
Create a Laravel Rule
Based on documentation, each ReCaptcha response token is valid for 2 minutes and can only be verified once to prevent replay attacks. If you need a new token, you need to refresh or re-run the ReCaptcha verification.
After you get the response token, you need to verify it within 2 minutes with ReCaptcha using the following API to ensure the token is valid.
https://recaptchaenterprise.googleapis.com/v1/projects/PROJECT_ID/assessments?key=API_KEY (POST)
This API required JSON body with following content
{
"event": {
"token": "Token from g-recaptcha-response",
"siteKey": "GOOGLE_RECAPTCHA_SITE_KEY",
"expectedAction": "Value from g-recaptcha-action"
}
}And the response should be like below
[
"name" => "projects/1037628514823/assessments/ab913a9764000000"
"event" => array:6 [
"token" => "TOKEN"
"siteKey" => "SITE KEY"
"userAgent" => ""
"userIpAddress" => ""
"expectedAction" => "login"
"hashedAccountId" => ""
]
"riskAnalysis" => [
"score" => 0.9
"reasons" => []
]
"tokenProperties" => [
"valid" => true
"invalidReason" => "INVALID_REASON_UNSPECIFIED"
"hostname" => "localhost"
"action" => "login"
"createTime" => "2022-07-14T07:07:15.050Z"
]
]
Now we know validation step and response, lets create a validation rule name ReCaptchaEnterpriseRule
php artisan make:rule ReCaptchaEnterpriseRule
And paste the below code
Note that, this rules only cater true or false condition based on the response. If you want to have extra validation, you may customize it
Add Validation rule to Login logic
Add extra validation in your controller logic to use the ReCaptchaEnterpriseRule
public function login(Request $request)
{
....
$request->validate([
'g-recaptcha-action' => 'required|string',
'g-recaptcha-response' => ['required', new ReCaptchaEnterpriseRule]
]);
...
}
For more convenience, i recommended to put any validation in the Request class, so that your controller won’t get messy
Testing and validation
By the time you submit the form, you will be able to utilize the ReCaptcha functionality successfully. If it is not working, i suggest you to debug or dump the request from the verification API to see the error messages or error codes provided in the response.
Just like that. Simple~ Hope it helps
Notes
To improve reCAPTCHA Enterprise’s risk model, Google recommend that you include reCAPTCHA Enterprise on every page of your site because it helps in understanding how real users and bots transition between different pages and actions.
References
Found this helpful?
If this article saved you time or solved a problem, consider supporting — it helps keep the writing going.
Originally published on Medium.
View on Medium