dskripchenko/yandex-smart-captcha

Yandex Smart Captcha

Maintainers

Package info

github.com/dskripchenko/yandex-smart-captcha

pkg:composer/dskripchenko/yandex-smart-captcha

Transparency log

Statistics

Installs: 2 772

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v1.3.0 2026-08-10 15:24 UTC

This package is auto-updated.

Last update: 2026-08-10 15:25:27 UTC


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).

🌐 English · Deutsch · Русский · 中文

Packagist License

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