Google reCaptcha v3 is a new version of reCaptcha where user doesn’t have to interact. It returns a score for each request which use to restrict form.
At the bottom of the page “protected by reCAPTCHA” icon is visible if integrated successfully.
In this tutorial, I show how you can add Google reCaptcha v3 to the form using the Laravel reCaptcha package in Laravel 9.
Contents
- Get reCAPTCHA Keys
- Update .env
- Install Laravel reCAPTCHA Package
- Publish package
- Update recaptcha.php
- Clear caches
- Route
- Controller
- View
- Output
- Conclusion
1. Get reCAPTCHA Keys
- Navigate to the following link and login into your account if not logged in.
- Following page will display.
- Here, enter label, select reCAPTCHA v3 from the reCAPTCHA type, enter your domain name without https e.g. makitweb.com. You can also specify
localhost
if you want to test it on your local system. - Check the
Accept the reCAPTCHA Terms of Service
and click the Submit button.
- Copy the site and secret keys.
2. Update .env
- Open
.env
file. - Create 2 variables for Google reCaptcha –
- RECAPTCHA_SITE_KEY – Assign copied site key.
- RECAPTCHA_SECRET_KEY – Assign copied secret key.
RECAPTCHA_SITE_KEY=6LdP-nIhAAAAAA6rzq7BTh_jKqIYeKMoaALxkKte RECAPTCHA_SECRET_KEY=6LdV-nIhAAAAAL-uFI4w9kQUaqMkeU2K3KojlXyE
3. Install Laravel reCAPTCHA Package
Install the package using composer –
composer require biscolab/laravel-recaptcha
4. Publish package
Run the command –
php artisan vendor:publish --provider="Biscolab\ReCaptcha\ReCaptchaServiceProvider"
5. Update recaptcha.php
- Open
config/recaptcha.php
file. - Update
'version'
value fromv2
tov3
if it is not set.
'version' => 'v3',
6. Clear caches
Run the following command –
php artisan config:cache
7. Route
- Open
routes/web.php
file. - Define 2 routes –
- / – Load index view.
- pages/store – Handle form submit.
Completed Code
<?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\PagesController; Route::get('/', [PagesController::class, 'index']); Route::post('pages/store', [PagesController::class, 'store'])->name('pages.store');
8. Controller
- Create
PagesController
Controller.
php artisan make:controller PagesController
- Include Validator –
use Illuminate\Support\Facades\Validator;
- Create 2 methods –
- index() – Load
index
view. - store() – Handle form submission.
- index() – Load
If validated successfully then set SESSION flash and redirect to /
route otherwise return to the page with the error.
Completed Code
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Validator; use Session; class PagesController extends Controller { public function index(){ return view('index'); } public function store(Request $request){ $validator = Validator::make($request->all(), [ 'name' => 'required', 'email' => 'required|email', 'message' => 'required', ]); if ($validator->fails()) { return redirect()->Back()->withInput()->withErrors($validator); }else{ Session::flash('message','Form submit Successfully.'); } return redirect('/'); } }
9. View
Create index.blade.php
file in resources/views/
folder.
HTML
Add <meta name="csrf-token">
to store csrf_token()
in content
attribute.
Display Bootstrap alert if SESSION is set.
Create <form action="{{ route('pages.store') }}" method="post" id="contactForm">
and add some elements.
reCaptcha Script
Add JavaScript code in <head>
section.
Add {!! htmlScriptTagJsApi() !!}
. Set 'callback_then' => 'callbackThen'
, and 'callback_catch' => 'callbackCatch'
.
Create 2 functions –
- callbackThen – Check recaptcha response. If the status is true and score is >= 0.6 means recaptcha is validated successfully otherwise display an error alert message and stop the page from submitting.
- callbackCatch – For handling errors.
Completed Code
<!DOCTYPE html> <html lang="en"> <head> <title>How to Add Google reCAPTCHA v3 to form in Laravel</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="csrf-token" content="{{ csrf_token() }}"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.min.js"></script> <!-- Include script --> <script type="text/javascript"> function callbackThen(response) { // read Promise object response.json().then(function(data) { console.log(data); if(data.success && data.score >= 0.6) { console.log('valid recaptcha'); } else { document.getElementById('contactForm').addEventListener('submit', function(event) { event.preventDefault(); alert('recaptcha error'); }); } }); } function callbackCatch(error){ console.error('Error:', error) } </script> {!! htmlScriptTagJsApi([ 'callback_then' => 'callbackThen', 'callback_catch' => 'callbackCatch', ]) !!} </head> <body> <!-- Alert message (start) --> @if(Session::has('message')) <div class="alert alert-success"> {{ Session::get('message') }} </div> @endif <!-- Alert message (end) --> <div class="container"> <h2>Contact form</h2> <form action="{{ route('pages.store') }}" method="post" id="contactForm"> @csrf <div class="form-group"> <label for="name">Name:</label> <input type="name" class="form-control" id="email" placeholder="Enter name" name="name" value="{{ old('name') }}"> @if($errors->has('name')) <small class="text-danger">{{ $errors->first('name') }}</small> @endif </div> <div class="form-group"> <label for="email">Email:</label> <input type="email" class="form-control" id="email" placeholder="Enter email" name="email" value="{{ old('email') }}"> @if($errors->has('email')) <small class="text-danger">{{ $errors->first('email') }}</small> @endif </div> <div class="form-group"> <label for="message">Message:</label> <textarea class="form-control" id="message" placeholder="Enter message" name="message">{{ old('message') }}</textarea> @if($errors->has('message')) <small class="text-danger">{{ $errors->first('message') }}</small> @endif </div> <button type="submit" class="btn btn-primary">Submit</button> </form> </div> </body> </html>
10. Output
11. Conclusion
Make sure to add <meta name="csrf-token" >
to store the CSRF token otherwise token is not readable and a verification request not be sent.
You can also view Google reCaptcha v2 integration in Laravel 8 here.
If you found this tutorial helpful then don't forget to share.