PHPackages                             rasuvaeff/yii3-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. [Validation &amp; Sanitization](/categories/validation)
4. /
5. rasuvaeff/yii3-recaptcha

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

rasuvaeff/yii3-recaptcha
========================

Google reCAPTCHA v2/v3 widget and validator for Yii3.

v1.0.3(3w ago)010BSD-3-ClausePHPPHP 8.3 - 8.5CI passing

Since Jun 2Pushed 1w agoCompare

[ Source](https://github.com/rasuvaeff/yii3-recaptcha)[ Packagist](https://packagist.org/packages/rasuvaeff/yii3-recaptcha)[ Docs](https://github.com/rasuvaeff/yii3-recaptcha)[ RSS](/packages/rasuvaeff-yii3-recaptcha/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (1)Dependencies (40)Versions (5)Used By (0)

rasuvaeff/yii3-recaptcha
========================

[](#rasuvaeffyii3-recaptcha)

[![Stable Version](https://camo.githubusercontent.com/dbb301bdfb0ef8a2828f6a1483f6ff5a67b6a24c9e5fe2344ed18d1d132cb763/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7261737576616566662f796969332d7265636170746368613f6c6162656c3d737461626c6526736f72745f73656d7665723d31)](https://packagist.org/packages/rasuvaeff/yii3-recaptcha)[![Total Downloads](https://camo.githubusercontent.com/df7a73ff79a1185a4d0b91e20e448b9d8f29dd353c5f10eb10269bade7fa43dd/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7261737576616566662f796969332d726563617074636861)](https://packagist.org/packages/rasuvaeff/yii3-recaptcha)[![Build](https://camo.githubusercontent.com/3cbdeb583bf6e7c701a1642795443f54aefe9a1318fde25e69a2f56cf15257de/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f7261737576616566662f796969332d7265636170746368612f6275696c642e796d6c3f6272616e63683d6d6173746572)](https://github.com/rasuvaeff/yii3-recaptcha/actions)[![Static analysis](https://camo.githubusercontent.com/7ee4de0e142ed370a2cf9260228fdec31b5c088521cc95ebb8124b8062cfe628/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f7261737576616566662f796969332d7265636170746368612f7374617469632d616e616c797369732e796d6c3f6272616e63683d6d6173746572266c6162656c3d737461746963253230616e616c79736973)](https://github.com/rasuvaeff/yii3-recaptcha/actions)[![Psalm level](https://camo.githubusercontent.com/96f0376e917393dc04f5e50ef34fa74f202272a3100aa70c66ece3282f6a2e36/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7073616c6d2d6c6576656c253230312d3134314634383f6c6f676f3d7073616c6d266c6f676f436f6c6f723d7768697465)](https://github.com/rasuvaeff/yii3-recaptcha/blob/master/psalm.xml)[![PHP](https://camo.githubusercontent.com/25cde32068139e9e57321b197ef0e52511172a4cd4095d0f31917f388c54fab2/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646570656e64656e63792d762f7261737576616566662f796969332d7265636170746368612f706870)](https://packagist.org/packages/rasuvaeff/yii3-recaptcha)[![License](https://camo.githubusercontent.com/9e354c19c8a5f4cb76facd26a2cadbc95869d23d92fe43a4739387d51a95e99f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f7261737576616566662f796969332d726563617074636861)](LICENSE.md)

Google reCAPTCHA v2 and v3 widgets, `yiisoft/form-model` fields, and a server-side validator for Yii3.

Provides `RecaptchaV2` / `RecaptchaV3` widgets and `RecaptchaV2Field` / `RecaptchaV3Field` form-model fields for rendering challenges, plus `RecaptchaV2Rule` / `RecaptchaV3Rule` with their handlers for server-side verification through the Yii validator pipeline. In a **headless setup**(SPA/Next.js frontend + API backend) you skip the rendering half entirely and use only the validator — see [Headless / API-only](#headless--api-only). HTTP calls go through any PSR-18 client.

> **Using an AI coding assistant?** [llms.txt](llms.txt) contains a compact API reference you can share with the model. Contributors: see [AGENTS.md](AGENTS.md).

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

[](#requirements)

RequirementVersionPHP`^8.3`A PSR-18 HTTP client + PSR-17 factoriesany implementation`yiisoft/widget``^2.2``yiisoft/html``^4.0``yiisoft/validator``^2.5``yiisoft/translator``^3.0``yiisoft/request-provider``^1.3``yiisoft/form` + `yiisoft/form-model``^1.0` / `^1.1` (form fields)Installation
------------

[](#installation)

```
composer require rasuvaeff/yii3-recaptcha
```

You also need a PSR-18 client and PSR-17 factories if your project doesn't already ship one:

```
composer require guzzlehttp/guzzle nyholm/psr7
# or another PSR-18 client plus PSR-17 factories
```

### DI configuration

[](#di-configuration)

The package ships `config/di.php` via `config-plugin`. Rule handlers are constructed by the validator's **container-backed handler resolver** (the Yii3 default via `yiisoft/config`), which autowires the client, the client-IP resolver and the optional translator — **no extra DI config required**.

> **Works out of the box; DI-injected when available.** The rule handlers take their dependencies (client, IP resolver, translator) as optional constructor arguments and fall back to `RecaptchaRegistry`, which the package's config-plugin **bootstrap** populates from the container. So they work with the `yiisoft/validator` default `SimpleRuleHandlerContainer` (no-arg `new`) with no extra config. When a container-backed resolver builds them, the injected deps win and the registry is never consulted.
>
> The application must provide a **PSR-18 `ClientInterface`** and PSR-17 factories (the `RecaptchaClient` is built from them) and set the keys in params (see [Dependency injection](#dependency-injection-yii3)). Two optional pure-DI setups if you'd rather not rely on the static fallback:
>
> ```
> // A) container-backed resolver (all rule handlers resolved via the container)
> RuleHandlerResolverInterface::class => RuleHandlerContainer::class,
>
> // B) keep the default resolver, pre-register the DI-built handlers as instances
> RuleHandlerResolverInterface::class => static fn (
>     RecaptchaV2RuleHandler $v2, RecaptchaV3RuleHandler $v3,
> ): SimpleRuleHandlerContainer => new SimpleRuleHandlerContainer([
>     RecaptchaV2RuleHandler::class => $v2,
>     RecaptchaV3RuleHandler::class => $v3,
> ]),
> ```

Headless / API-only
-------------------

[](#headless--api-only)

For a **SPA/Next.js frontend + Yii3 API backend** the widgets and fields are not used — the frontend renders reCAPTCHA (e.g. `react-google-recaptcha`) and calls `grecaptcha.execute(siteKey, { action })`, then sends the token to the API. The backend only **verifies** it. Put the token on a request DTO property and attach the rule:

```
final class LoginRequest
{
    #[RecaptchaV3Rule(action: 'login', threshold: 0.5)]
    public string $recaptchaToken = '';
}
```

Map the incoming token (JSON body field or a header such as `X-Recaptcha-Token`) to that property, then run your normal validation. Different endpoints use different `action` names and thresholds. To make a graduated (allow / challenge / deny) decision on the raw score instead of a pass/fail rule, verify imperatively:

```
$result = $client->verifyV3($token);        // VerificationResult
if ($result->isTransportError()) { /* siteverify down — decide policy */ }
$score = $result->score;                     // apply your own score bands
```

Behind a proxy/CDN, bind a proxy-aware client-IP resolver — see [Client IP behind a proxy](#client-ip-behind-a-proxy).

Usage
-----

[](#usage)

### reCAPTCHA v2

[](#recaptcha-v2)

```
use Rasuvaeff\Yii3Recaptcha\RecaptchaV2;
use Rasuvaeff\Yii3Recaptcha\RecaptchaV2Theme;
use Rasuvaeff\Yii3Recaptcha\RecaptchaV2Size;

// siteKey comes from DI config (RecaptchaConfig.siteKeyV2)
echo RecaptchaV2::widget()
    ->withTheme(RecaptchaV2Theme::Dark)
    ->withSize(RecaptchaV2Size::Normal);
```

```
use Rasuvaeff\Yii3Recaptcha\RecaptchaV2Rule;

class LoginForm
{
    #[RecaptchaV2Rule]
    public string $gRecaptchaResponse = '';
}
```

> **Field name mapping with Yii3 FormModel**
>
> Google's reCAPTCHA v2 widget always submits the response token as `g-recaptcha-response` (with hyphens). PHP does **not** normalize hyphens in POST keys, so `FormModel` will never receive the token if it expects `gRecaptchaResponse`directly.
>
> Use `withResponseFieldName()` to bind the token to your model property automatically — the widget renders a hidden input and the required JS copy callback:
>
> ```
>
