dskripchenko / yandex-smart-captcha
Yandex Smart Captcha
Package info
github.com/dskripchenko/yandex-smart-captcha
pkg:composer/dskripchenko/yandex-smart-captcha
Requires
- php: ^8.2
- ext-json: *
- dskripchenko/php-array-helper: ^1.1
- guzzlehttp/guzzle: ^7.0
- laravel/framework: ^11.0 || ^12.0 || ^13.0
Requires (Dev)
- laravel/pint: ^1.0
- orchestra/testbench: ^9.0 || ^10.0 || ^11.0
- phpstan/phpstan: ^2.0
README
Server-side validation of Yandex SmartCaptcha tokens for Laravel: a validation rule, a facade and a switch that turns verification off where you don't want it (local development, tests).
Requirements
PHP 8.2–8.5 · Laravel 11 / 12 / 13.
Install
composer require dskripchenko/yandex-smart-captcha
The service provider is auto-discovered. Publish the config if you want to edit it directly rather than through the environment:
php artisan vendor:publish --provider="Dskripchenko\YandexSmartCaptcha\Providers\YandexSmartCaptchaServiceProvider"
Configure
YANDEX_SMART_CAPTCHA_ENABLE=true YANDEX_SMART_CAPTCHA_CLIENT_KEY=your-client-key YANDEX_SMART_CAPTCHA_SERVER_KEY=your-server-key
YANDEX_SMART_CAPTCHA_ENABLE defaults to false, so a fresh install never
blocks a form until you have keys. Leave it off in tests and local development —
the rule then passes without calling Yandex.
| Key | Default | Meaning |
|---|---|---|
enable |
false |
Whether tokens are verified at all |
url |
https://smartcaptcha.yandexcloud.net |
Verification endpoint |
client_key |
— | Key used by the widget in the browser |
server_key |
— | Key used for server-side verification |
error_message |
Smart captcha validation error |
Message returned on a failed check |
connect_timeout |
2.0 |
Seconds to wait for the connection |
timeout |
5.0 |
Seconds to wait for the whole request |
fail_open |
false |
What to do when the endpoint cannot be reached |
When Yandex cannot be reached
Verification is an outgoing call made while a visitor's request is held open, so the endpoint has to be reachable from your server — not only from the visitor's browser. Two settings decide what happens when it is not.
The timeouts are bounded on purpose. Guzzle waits forever by default, and a hanging endpoint holds the worker with it; on a pooled runtime (Octane, RoadRunner, Swoole) a handful of held workers exhausts the pool, so an unreachable captcha service takes the whole site down with it.
fail_open is the policy choice, and it is a real trade in both directions:
false(default) — an unreachable endpoint counts as a failed check. Nothing gets through unverified, and every protected form stays closed until the service comes back.true— the submission is allowed. Choose it only where the captcha is one layer among several (rate limit, honeypot, timing), because anyone able to block the endpoint can then switch the captcha off by blocking it.
It applies to transport failures only. An endpoint that answered — with a
rejection or with an error status — has given a verdict, and fail_open never
overrides one.
Usage
As a validation rule
public function rules(): array { return [ 'token' => 'yandex_smart_captcha', ]; }
The rule reads the client's IP address from the request, so a token issued for another address is rejected.
Through the facade
use Dskripchenko\YandexSmartCaptcha\Facades\YandexSmartCaptcha; $valid = YandexSmartCaptcha::validate( token: $request->input('token'), ip: $request->ip(), // null skips the address check throwable: true, // throw on failure instead of returning false );
License
MIT © Denis Skripchenko