PHPackages                             laragear/recaptcha - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. laragear/recaptcha

Abandoned → [laragear/turnstile](/?search=laragear%2Fturnstile)ArchivedLibrary[Utility &amp; Helpers](/categories/utility)

laragear/recaptcha
==================

Integrate reCAPTCHA using async HTTP/3, making your app fast with a few lines.

v2.1.1(8mo ago)2097.6k↓47.6%2MITPHPPHP ^8.1

Since Feb 16Pushed 8mo ago2 watchersCompare

[ Source](https://github.com/Laragear/ReCaptcha)[ Packagist](https://packagist.org/packages/laragear/recaptcha)[ Fund](https://github.com/sponsors/DarkGhostHunter)[ Fund](https://paypal.me/darkghosthunter)[ RSS](/packages/laragear-recaptcha/feed)WikiDiscussions 2.x Synced 1mo ago

READMEChangelog (8)Dependencies (7)Versions (13)Used By (0)

Abandoned for [Laragear Turnstile](https://github.com/Laragear/Turnstile)
=========================================================================

[](#abandoned-for-laragear-turnstile)

Due to Google reCAPTCHA becoming a [paid service](https://cloud.google.com/recaptcha/docs/compare-tiers) with only 1,000 free *assessments*, this package has been abandoned.

If you need a replacement for this library using other service, you can use [Laragear Turnstile](https://github.com/Laragear/Turnstile), a new Laravel package developed for [Cloudflare Turnstile](https://www.cloudflare.com/application-services/products/turnstile/) which is far less abrasive than Google reCAPTCHA and with unlimited requests.

---

ReCaptcha
=========

[](#recaptcha)

[![Latest Version on Packagist](https://camo.githubusercontent.com/ac43cc377a76d547785a5a58c1c666ee7c995f06d343e4e15af18553050b94e6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c617261676561722f7265636170746368612e737667)](https://packagist.org/packages/laragear/recaptcha)[![Latest stable test run](https://github.com/Laragear/ReCaptcha/workflows/Tests/badge.svg)](https://github.com/Laragear/ReCaptcha/actions)[![Codecov coverage](https://camo.githubusercontent.com/060d4d993942ded01ccfdfa8b12e049467d4586455ff013f9b39cc44213f6ef4/68747470733a2f2f636f6465636f762e696f2f67682f4c617261676561722f5265436170746368612f6272616e63682f312e782f67726170682f62616467652e7376673f746f6b656e3d355536424a5545413454)](https://codecov.io/gh/Laragear/ReCaptcha)[![Maintainability](https://camo.githubusercontent.com/6b928e5bd2e43ba2102e1e16c1a8d7bf5ee353e5593bbbf729d09a0e1e2ccd27/68747470733a2f2f6170692e636f6465636c696d6174652e636f6d2f76312f6261646765732f62383839646563626336616636613163666433612f6d61696e7461696e6162696c697479)](https://codeclimate.com/github/Laragear/ReCaptcha/maintainability)[![Sonarcloud Status](https://camo.githubusercontent.com/3834020a3b0841385d473d119da85ea086fd81e7efe44006e782f3c3abd5c35b/68747470733a2f2f736f6e6172636c6f75642e696f2f6170692f70726f6a6563745f6261646765732f6d6561737572653f70726f6a6563743d4c617261676561725f526543617074636861266d65747269633d616c6572745f737461747573)](https://sonarcloud.io/dashboard?id=Laragear_ReCaptcha)[![Laravel Octane Compatibility](https://camo.githubusercontent.com/70359a356da237cd29561bc5d0bb80baae775b5ff62f288ed324755382858342/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2532304f6374616e652d436f6d70617469626c652d737563636573733f7374796c653d666c6174266c6f676f3d6c61726176656c)](https://laravel.com/docs/11.x/octane#introduction)

Integrate reCAPTCHA using **async HTTP/3**, making your app **fast** with a few lines.

```
use Illuminate\Support\Facades\Route;

Route::post('login', function () {
    // ...
})->middleware('recaptcha:checkbox');
```

Become a sponsor
----------------

[](#become-a-sponsor)

[![](.github/assets/support.png)](https://github.com/sponsors/DarkGhostHunter)

Your support allows me to keep this package free, up-to-date and maintainable. Alternatively, you can **[spread the word!](http://twitter.com/share?text=I%20am%20using%20this%20cool%20PHP%20package&url=https://github.com%2FLaragear%2FReCaptcha&hashtags=PHP,Laravel)**

Requirements
------------

[](#requirements)

- Laravel 10 or later

Installation
------------

[](#installation)

You can install the package via Composer:

```
composer require laragear/recaptcha
```

Set up
------

[](#set-up)

Add the reCAPTCHA keys for your site to the environment file of your project. You can add each of them for reCAPTCHA v2 **checkbox**, **invisible**, **Android**, and **score**.

If you don't have one, generate it in your [reCAPTCHA Admin panel](https://www.google.com/recaptcha/admin/).

```
RECAPTCHA_CHECKBOX_SECRET=6t5geA1UAAAAAN...
RECAPTCHA_CHECKBOX_KEY=6t5geA1UAAAAAN...

RECAPTCHA_INVISIBLE_SECRET=6t5geA2UAAAAAN...
RECAPTCHA_INVISIBLE_KEY=6t5geA2UAAAAAN...

RECAPTCHA_ANDROID_SECRET=6t5geA3UAAAAAN...
RECAPTCHA_ANDROID_KEY=6t5geA3UAAAAAN...

RECAPTCHA_SCORE_SECRET=6t5geA4UAAAAAN...
RECAPTCHA_SCORE_KEY=6t5geA4UAAAAAN...
```

This allows you to check different reCAPTCHA mechanisms using the same application, in different environments.

Note

ReCaptcha already comes with v2 keys for local development. For v3, you will need to create your own set of credentials once on production.

Usage
-----

[](#usage)

Usage differs based on if you're using checkbox, invisible, Android challenges, or the v3 score-driven challenge.

### Checkbox, invisible and Android challenges

[](#checkbox-invisible-and-android-challenges)

After you integrate reCAPTCHA into your frontend or Android app, set the ReCaptcha middleware in the `POST` routes where a form with reCAPTCHA is submitted. The middleware will catch the `g-recaptcha-response` input (you can change it later) and check if it's valid.

To declare the middleware just use the `ReCaptcha` middleware builder:

- `ReCaptcha::checkbox()` for explicitly rendered checkbox challenges.
- `ReCaptcha::invisible()` for invisible challenges.
- `ReCaptcha::android()` for Android app challenges.

```
use App\Http\Controllers\ContactController;
use Laragear\ReCaptcha\Http\Middleware\Builders\ReCaptcha;
use Illuminate\Support\Facades\Route;

Route::post('contact', [ContactController::class, 'send'])
    ->middleware(ReCaptcha::invisible()->forGuests('web')->remember())
```

If for some reason the challenge is not a success, the validation will immediately kick in and throw a `ValidationException`, returning the user back to the form.

#### Remembering challenges

[](#remembering-challenges)

To avoid asking for challenges over and over again, you can "remember" the challenge for a given set of minutes. This can be [enabled globally](#remember), but you may prefer to do it in a per-route basis.

Simple use the `remember()` method. You can set the number of minutes to override the [global parameter](#remember). Alternatively, `rememberForever()` will remember the challenge forever.

```
use App\Http\Controllers\Auth\LoginController;
use Laragear\ReCaptcha\Http\Middleware\Builders\ReCaptcha;
use Illuminate\Support\Facades\Route

Route::post('login', [LoginController::class, 'login'])
     ->middleware(ReCaptcha::invisible()->remember());

Route::post('message', [ChatController::class, 'login'])
     ->middleware(ReCaptcha::checkbox()->rememberForever());
```

You should use this in conjunction with the `@robot` directive in your Blade templates to render a challenge when the user has not successfully done one before.

```
@robot

@endrobot
```

Tip

Good places to remember a challenge for some minutes are forms which are expected to fail, or when you have multiple forms the user may jump between.

#### Changing the input name

[](#changing-the-input-name)

You can change the input name from `g-recaptcha-response`, which is the default, to anything using `input()`.

```
use App\Http\Controllers\Auth\LoginController;
use Laragear\ReCaptcha\Http\Middleware\Builders\ReCaptcha;
use Illuminate\Support\Facades\Route

Route::post('login', [LoginController::class, 'login'])
     ->middleware(ReCaptcha::checkbox()->input('recaptcha_input'));
```

### Score-driven challenge

[](#score-driven-challenge)

The reCAPTCHA v3 middleware works differently from v2. This response is *always* a success, but the challenge scores between `0.0` and `1.0`. Human-like interaction will be higher, while robots will score lower. The default threshold is `0.5`, but this can be changed globally or per-route.

To start using it, simply use the `ReCaptcha::score()` method to your route.

```
use App\Http\Controllers\CommentController;
use Laragear\ReCaptcha\Http\Middleware\Builders\ReCaptcha;
use Illuminate\Support\Facades\Route

Route::post('comment', [CommentController::class, 'create'])
     ->middleware(ReCaptcha::score());
```

Once the challenge has been received in your controller, you will have access to two methods from the Request class or instance: `isHuman()` and `isRobot()`, which may return `true` or `false`:

```
use App\Models\Post;
use Illuminate\Http\Request;

public function store(Request $request, Post $post)
{
    $request->validate([
        'body' => 'required|string|max:255'
    ]);

    $comment = $post->comment()->make($request->only('body'));

    // Flag the comment as "moderated" if it was a written by robot.
    if ($request->isRobot()) {
        $comment->markAsModerated();
    }

    $comment->save();

    return view('post.comment.show', ['comment' => $comment]);
}
```

You can also have access to the response from reCAPTCHA using the `response()` method of the `ReCaptcha` facade:

```
use Laragear\ReCaptcha\Facades\ReCaptcha;

$response = ReCaptcha::response();

if ($response->score > 0.2) {
    return 'Try again!';
}
```

Warning

Be careful of calling `response()`, as it will throw an exception on controllers without challenges.

#### Threshold, action and input name

[](#threshold-action-and-input-name)

The middleware accepts three additional parameters using the middleware helper.

1. `threshold()`: The value that must be **above or equal** to be considered human.
2. `action()`: The action name to optionally check against.
3. `input()`: The name of the reCAPTCHA input to verify.

```
use App\Http\Controllers\CommentController;
use Laragear\ReCaptcha\Http\Middleware\Builders\ReCaptcha;
use Illuminate\Support\Facades\Route

Route::post('comment', [CommentController::class, 'store'])
     ->middleware(ReCaptcha::score()->threshold(0.7)->action('post-comment')->input('my_score_input');
```

Important

When checking the action name, ensure your frontend action matches with the expected in the middleware.

#### Bypassing on authenticated users

[](#bypassing-on-authenticated-users)

Sometimes you may want to bypass reCAPTCHA checks when there is an authenticated user, or automatically receive it as a "human" on score-driven challenges, specially on recurrent actions or when the user already has completed a challenge (like on logins).

To exclude authenticated user you can use `forGuests()`, and specify the guards if necessary.

```
use App\Http\Controllers\CommentController;
use App\Http\Controllers\MessageController;
use DarkGhostHunter\Captcha\ReCaptcha;
use Illuminate\Support\Facades\Route

// Don't challenge users authenticated on the default (web) guard.
Route::post('message/send', [MessageController::class, 'send'])
     ->middleware(ReCaptcha::invisible()->forGuests());

// Don't challenge users authenticated on the "admin" and "moderator" guards.
Route::post('comment/store', [CommentController::class, 'store'])
     ->middleware(ReCaptcha::score(0.7)->action('comment.store')->forGuests('admin', 'moderator'));
```

Then, in your blade files, you can easily skip the challenge with the `@guest` or `@auth` directives.

```

    @auth
        Post comment
    @else

            Post comment

    @endauth

```

#### Faking reCAPTCHA scores

[](#faking-recaptcha-scores)

You can easily fake a reCAPTCHA response score in your local development by setting `RECAPTCHA_FAKE` to `true`.

```
RECAPTCHA_FAKE=true
```

This environment variable allows to fake a robot responses by filling the `is_robot` input in your form.

```

    @env('local')

    @endenv

        Post comment

```

Confirmation middleware
-----------------------

[](#confirmation-middleware)

ReCaptcha comes with a handy middleware to confirm with a simple reCAPTCHA Checkbox challenge, much like the [password confirmation](https://laravel.com/docs/authentication#password-confirmation-protecting-routes) middleware included in Laravel.

First, set the route to protect using the `recaptcha.confirm` middleware.

```
use Illuminate\Support\Facades\Route;

Route::get('/settings', function () {
    // ...
})->middleware('recaptcha.confirm');

Route::post('/settings', function () {
    // ...
})->middleware('recaptcha.confirm');
```

Once done, ensure you have also a `recaptcha.confirm` route to receive the redirected user, and one to receive the challenge at the same path (as the view `POST` request does). ReCaptcha comes with a controller and a basic view that you can use out of the box:

```
use Illuminate\Support\Facades\Route;
use Laragear\ReCaptcha\Http\Controllers\ConfirmationController;

Route::get('recaptcha', [ConfirmationController::class, 'show'])
    ->name('recaptcha.confirm');

Route::post('recaptcha', [ConfirmationController::class, 'confirm'])
```

When the user tries to enter the route, it will be redirected to the view asking to resolve a reCAPTCHA challenge. Once done, it will be redirected to the intended URL.

[![img.png](.github/assets/img.png)](.github/assets/img.png)

The middleware it's compatible with [remembering challenges](#remember), and will use the default amount of time to not ask again if remembering only when it's enabled globally, otherwise it will be asked to confirm every time.

You can configure the route name and the guards to bypass the confirmation if the user is authenticated after the first argument.

```
use Illuminate\Support\Facades\Route;

Route::get('/settings', function () {
    // ...
})->middleware('recaptcha.confirm:my-custom-route,web,admin');
```

Frontend integration
--------------------

[](#frontend-integration)

[Check the official reCAPTCHA documentation](https://developers.google.com/recaptcha/intro) to integrate the reCAPTCHA script in your frontend, or inside your Android application.

You can use the `recaptcha()` helper to output the site key depending on the challenge version you want to render: `checkbox`, `invisible`, `android` or `score` (v3).

```

        Login

```

Advanced configuration
----------------------

[](#advanced-configuration)

ReCaptcha is intended to work out-of-the-box, but you can publish the configuration file for fine-tuning the reCAPTCHA verification.

```
php artisan vendor:publish --provider="Laragear\ReCaptcha\ReCaptchaServiceProvider" --tag="config"
```

You will get a config file with this array:

```
