1150 0 0 0
Last Updated : 2025-04-28 22:00:31
In this snippet I will explain how to add google reCAPTCHA v3 to your Laravel Forms
Hello guys,
Google’s reCAPTCHA v3 was introduced in late 2018 and brings a range of benefits over reCAPTCHA v2 and its familiar “I’m not a robot” checkbox and “select all the traffic lights” style of challenges.
Instead of requiring the user to complete these challenges, v3 calculates a score based on a number of factors to determine whether the user is a human or not, then allows the website to take an appropriate action based on this score.
Google understandably hasn’t made public the factors that build up this score but it is believed to include:
And undoubtedly a number of other elements.
The benefits of v3 over v2 include:
So let's get started
1- got to reCAPTCHA admin page -> register a new site -> provide any label name you want -> choose reCAPTCHA type (v3) -> provide your domain(s) (localhost or any domain name) -> accepts terms -> then submit .
2- after submitting new site on reCAPTCHA admin page -> this will give you site key and secret key -> copy them (we will need them later).
3- go to your form blade file -> add a hidden field in your form like this
<input type="hidden" name="recaptcha" id="recaptcha">
4- after adding recaptcha hidden field -> add this script to your form blade file like this
<script src="https://www.google.com/recaptcha/api.js?render={{ config('services.recaptcha.sitekey') }}"></script>
<script>
grecaptcha.ready(function() {
grecaptcha.execute('{{ config('services.recaptcha.sitekey') }}', {action: 'submit'}).then(function(token) {
if (token) {
document.getElementById('recaptcha').value = token;
}
});
});
</script>
Note the {action: 'contact'}
part, you can specify different actions for different parts of your website and see the data in your admin console.
Important, from Google’s docs: “actions may only contain alphanumeric characters and slashes, and must not be user-specific.”, this means you cannot use ‘contact-us’ for example, you’ll receive an error.
Also note the lines containing {{ config('services.recaptcha.sitekey') }}
, you could simply paste your site key here, but it’s better to set these in config and env files.
5- open config/services.php and this code
'recaptcha' => [
'sitekey' => env('RECAPTCHA_SITEKEY'),
'secret' => env('RECAPTCHA_SECRET'),
],
6- in your .env file add this code
RECAPTCHA_SECRET=YOUR_RECAPTCHA_SECRET_KEY // your secret key generated from reCAPTCHA admin page
RECAPTCHA_SITEKEY=YOUR_RECAPTCHA_SITE_KEY // your site key generated from reCAPTCHA admin page
7- in your controller that manages your contact form within the method that sends your form data for expample store() method in your ContactController add this code
/**
* Store a newly created resource in storage.
*
* @param \App\Http\Requests\StoreMessageRequest $request
* @return \Illuminate\Http\Response
*/
public function store(StoreMessageRequest $request)
{
$url = 'https://www.google.com/recaptcha/api/siteverify';
$remoteip = $_SERVER['REMOTE_ADDR'];
$recapcha_data = [
'secret' => config('services.recaptcha.secret'),
'response' => $request->get('recaptcha'),
'remoteip' => $remoteip
];
$options = [
'http' => [
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($recapcha_data)
]
];
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
$resultJson = json_decode($result);
if ($resultJson->success != true) {
return back()->withErrors(['captcha' => 'ReCaptcha Error']);
}
if ($resultJson->score >= 0.3) {
// Validation was successful, add your form submission logic here
// This is my data logic
$data = $request->validated();
$message = Message::create([
'name' => $data['name'],
'email' => $data['email'],
'phone' => $data['phone'],
'type_id' => $data['type_id'],
'description' => $data['description'],
]);
if ($request->hasFile('file')) {
$file = $request->file('file');
$name = time().'-'.hexdec(\uniqid()).'.'.$file->getClientOriginalExtension();
$destinationPath = public_path('storage/messages/');
$file->move($destinationPath, $name);
$message->file = $name;
$message->save();
}
return response()->json(['success'=>'Created Successfully']);
// This is my data logic
} else {
return back()->withErrors(['captcha' => 'ReCaptcha Error']);
}
}
8- don't forget to modify your StoreMessageRequest file to include recaptcha field like this
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required',
'email' => 'required_without:phone|email',
'phone' => 'sometimes|required_without:email',
'file' => 'sometimes|mimes:pdf|max:5048',
'description' => 'sometimes|nullable',
'type_id' => 'required',
'recaptcha' => 'required', // add this line to include recaptcha field in the request
];
}