PHPackages                             edulazaro/laracaptcha - 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. edulazaro/laracaptcha

ActiveLibrary

edulazaro/laracaptcha
=====================

Driver-based captcha for Laravel: Cloudflare Turnstile and Google reCAPTCHA v2/v3 behind a single API

1.0.0(1mo ago)02↓66.7%MITPHPPHP ^8.2

Since Jul 17Pushed 1mo agoCompare

[ Source](https://github.com/edulazaro/laracaptcha)[ Packagist](https://packagist.org/packages/edulazaro/laracaptcha)[ RSS](/packages/edulazaro-laracaptcha/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (3)Versions (2)Used By (0)

[![Laracaptcha](art/banner.png)](art/banner.png)

Laracaptcha
===========

[](#laracaptcha)

Driver-based captcha for Laravel. One API for **Cloudflare Turnstile** and **Google reCAPTCHA v2/v3**: switch providers by changing one env variable, no code changes.

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

[](#installation)

```
composer require edulazaro/laracaptcha
```

Set your driver and keys in `.env`:

```
CAPTCHA_DRIVER=turnstile

TURNSTILE_KEY=0x4AAA...
TURNSTILE_SECRET=0x4AAA...

# Or for reCAPTCHA (v2 / v3):
# CAPTCHA_DRIVER=recaptcha_v2
# RECAPTCHA_KEY=...
# RECAPTCHA_SECRET=...
```

Optionally publish the config:

```
php artisan vendor:publish --tag=laracaptcha-config
```

Usage
-----

[](#usage)

### In a form

[](#in-a-form)

Drop the widget component inside any form. It renders the right markup and loads the provider script for the configured driver:

```

    @csrf
    ...

    Register

```

For reCAPTCHA v3 the widget is invisible and tokens are generated on submit; you can tag the action: ``.

### Validating the token

[](#validating-the-token)

Use the validation rule on the token field. The field name depends on the provider (`cf-turnstile-response` for Turnstile, `g-recaptcha-response` for reCAPTCHA); get it dynamically with `Captcha::responseField()`:

```
use EduLazaro\Laracaptcha\Rules\Captcha;
use EduLazaro\Laracaptcha\Facades\Captcha as CaptchaFacade;

$request->validate([
    CaptchaFacade::responseField() => ['required', new Captcha],
]);
```

The rule includes replay protection: a token that already passed once is rejected (configurable via `prevent_reuse` / `reuse_ttl`).

### Verifying manually

[](#verifying-manually)

```
use EduLazaro\Laracaptcha\Facades\Captcha;

$result = Captcha::verify($token, $request->ip());

$result->success;    // bool
$result->score;      // float|null (reCAPTCHA v3)
$result->errorCodes; // array
```

Use a specific driver regardless of the default: `Captcha::driver('recaptcha_v3')->verify($token)`.

### Testing

[](#testing)

```
use EduLazaro\Laracaptcha\Facades\Captcha;

$fake = Captcha::fake();                 // all verifications pass
$fake = Captcha::fake(success: false);   // all verifications fail
$fake = Captcha::fake(score: 0.9);       // pass with a score

$fake->attempts(); // recorded [token, ip] pairs
```

No HTTP requests are made while faked.

### Dev keys

[](#dev-keys)

Cloudflare publishes always-pass test keys for local development: sitekey `1x00000000000000000000AA`, secret `1x0000000000000000000000000000000AA`.

Sponsors
--------

[](#sponsors)

Laracaptcha is supported by the following sponsors. Thank you for keeping it growing:

 [![Kenodo](art/logo-kenodo.png)](https://kenodo.com) [Kenodo](https://kenodo.com) [![AndorraDev](art/logo-andorradev.png)](https://andorradev.com) [AndorraDev](https://andorradev.com)

Author
------

[](#author)

Created by [Edu Lazaro](https://edulazaro.com)

License
-------

[](#license)

Laracaptcha is open-sourced software licensed under the [MIT license](LICENSE).

###  Health Score

38

—

LowBetter than 82% of packages

Maintenance90

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

46d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/6a3c47449dfb2ec121aa410da024f47586b87cc2799a825f0418e6c5e5904955?d=identicon)[edulazaro](/maintainers/edulazaro)

---

Top Contributors

[![edulazaro](https://avatars.githubusercontent.com/u/7797530?v=4)](https://github.com/edulazaro "edulazaro (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/edulazaro-laracaptcha/health.svg)

```
[![Health](https://phpackages.com/badges/edulazaro-laracaptcha/health.svg)](https://phpackages.com/packages/edulazaro-laracaptcha)
```

###  Alternatives

[backpack/crud

Quickly build admin interfaces using Laravel, Bootstrap and JavaScript.

3.4k3.8M231](/packages/backpack-crud)[unopim/unopim

UnoPim Laravel PIM

10.9k2.6k](/packages/unopim-unopim)[statamic-rad-pack/runway

Eloquently manage your database models in Statamic.

138249.0k8](/packages/statamic-rad-pack-runway)[duncanmcclean/statamic-cargo

Comprehensive e-commerce addon for Statamic. Build bespoke e-commerce sites without the complexity.

3622.8k](/packages/duncanmcclean-statamic-cargo)[ecotone/laravel

Ecotone for Laravel — CQRS, Event Sourcing, Sagas, Durable Workflows, and Outbox on top of Laravel Queue, via PHP attributes.

21336.4k4](/packages/ecotone-laravel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
