PHPackages                             forutan/ccaptcha - 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. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. forutan/ccaptcha

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

forutan/ccaptcha
================

Forutan CCaptcha is a lightweight, customizable Laravel library for secure, human-verification circle-based captchas. Easily integrate with any Laravel project to protect forms, logins, and sensitive actions with a visually interactive captcha system.

1.0.0(6mo ago)06proprietaryPHPPHP ^8.1

Since Oct 24Pushed 6mo agoCompare

[ Source](https://github.com/yaservaziri/ForutanCCaptcha)[ Packagist](https://packagist.org/packages/forutan/ccaptcha)[ Fund](https://yaservaziri.github.io/ForutanCCaptcha/donate.html)[ RSS](/packages/forutan-ccaptcha/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (5)Versions (2)Used By (0)

📦 Install via [Packagist](https://packagist.org/packages/forutan/ccaptcha)
🐙 View source on [GitHub](https://github.com/yaservaziri/ForutanCCaptcha)

CCaptcha – Laravel Image-Based CAPTCHA
======================================

[](#ccaptcha--laravel-image-based-captcha)

**Forutan CCaptcha** is a lightweight, customizable Laravel package that adds an interactive, circle-based CAPTCHA system to protect your forms, logins, and sensitive routes.
It ensures that only real humans can pass your verification flow — without ugly distorted text or annoying puzzles.

---

🚀 Features
----------

[](#-features)

- ✅ Circle-based, click-to-verify CAPTCHA
- 🧠 Human-friendly &amp; accessible design
- 🔒 Built-in brute-force protection and blocking
- 🕒 Time-based expiration control
- ⚡ Easy Laravel integration with middleware &amp; routes
- 🖼️ Optimized background image pre-processing command
- 🧩 Works out of the box — no external APIs or keys

---

[![CCaptcha Preview](assets/ccaptcha.png)](assets/ccaptcha.png)

---

📦 Installation
--------------

[](#-installation)

Install the package via Composer:

```
composer require forutan/ccaptcha
```

---

🖼️ Prepare CAPTCHA Images
-------------------------

[](#️-prepare-captcha-images)

To make the circle CAPTCHA more resistant against bots and OCR attacks, **we use randomized background images** behind the circles.
These images create visual noise and texture that make it much harder for automated scripts to detect patterns — while keeping the challenge easy for humans.

You can use your own background images (e.g. nature, textures, abstract art) or rely on the default ones bundled with the package.

Before using them in production, it's **strongly recommended** to preprocess the images to:

- 🧹 **Remove all EXIF/metadata** (to protect user privacy)
- 📏 **Resize** them to the optimal dimensions for the captcha
- 🗜️ **Compress** them for fast loading
- 🧩 **Standardize format** to `.jpg`

This can be done using the included Artisan command:

```
php artisan ccaptcha:prepare-images
```

By default, this command uses the package’s internal seed images. You can also specify your own image source directory:

```
php artisan ccaptcha:prepare-images --from=/path/to/your/images
```

All cleaned and resized images will be stored securely in:

```
storage/app/private/ccaptcha/

```

🛡️ Middleware Usage
-------------------

[](#️-middleware-usage)

Protect your routes with the `ccaptcha.verified` middleware and a context name (e.g. login, checkout, comment, etc.):

```
Route::get('/dashboard', function () {
    // Protected content here
})->middleware('ccaptcha.verified:login');

Route::middleware('ccaptcha.verified:checkout')->group(function () {
    Route::get('/checkout', fn () => view('checkout'));
    Route::post('/checkout/pay', fn () => 'Processing payment...');
});
```

Each context is validated independently, so you can use different CAPTCHA challenges across different parts of your app.

---

⚙️ Configuration
----------------

[](#️-configuration)

Customize UI and logic with the following:

### Blade View

[](#blade-view)

```
php artisan vendor:publish --tag=ccaptcha-views
```

Now edit it in:

```
resources/views/vendor/ccaptcha/

```

### Config File

[](#config-file)

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

Now edit in:

```
config/ccaptcha.php

```

Sample Settings:: You can define different settings per context (e.g. login, checkout, comment) for maximum flexibility.

```
    /*
    |--------------------------------------------------------------------------
    | CAPTCHA Expiration
    |--------------------------------------------------------------------------
    |
    | Determines how long (in seconds) a generated captcha remains valid
    | before it expires and requires regeneration.
    |
    */
    'expire_seconds' => 30,

    /*
    |--------------------------------------------------------------------------
    | Attempt & Blocking Policy
    |--------------------------------------------------------------------------
    |
    | - max_attempts: number of failed verifications allowed per session
    | - block_duration_minutes: user is blocked for this many minutes after
    |   exceeding max_attempts.
    |
    */
    'max_attempts' => 5,
    'block_duration_minutes' => 60,

    /*
    |--------------------------------------------------------------------------
    | Routing & Middleware
    |--------------------------------------------------------------------------
    |
    | The prefix defines the base URL for captcha routes.
    | The middleware stack defines what should run before showing captcha.
    |
    */
    'route_prefix' => 'ccaptcha',
    'middleware' => ['web'],

    /*
    |--------------------------------------------------------------------------
    | Rate Limiting
    |--------------------------------------------------------------------------
    |
    | These throttle settings prevent abuse or spam requests
    | for both showing and verifying captcha.
    | Format: ","
    |
    */
    'throttle' => [
        'show' => '60,1',
        'verify' => '20,1',
    ],

    /*
    |--------------------------------------------------------------------------
    | Redirects
    |--------------------------------------------------------------------------
    |
    | Define where users should be redirected after successfully passing
    | the captcha challenge. You can specify per-context redirects if needed.
    |
    */
    'redirect_on_pass' => [
        'default' => '/',
    ],

    /*
    |--------------------------------------------------------------------------
    | Image Settings
    |--------------------------------------------------------------------------
    |
    | Default image processing configuration used by the
    | `ccaptcha:prepare-images` command and the controller.
    |
    | - image_width / image_height define final image dimensions
    | - image_quality controls compression level (1–100)
    | - storage_path defines where prepared captcha images are stored
    |
    */
    'image_width' => 500,
    'image_height' => 400,
    'image_quality' => 90,
    'storage_path' => storage_path('app/private/ccaptcha'),
    'radius_min' => 20,
    'radius_max' => 35,
    'min_circle_count' => 10,
    'max_circle_count' => 15
```

---

🤝 Contributing
--------------

[](#-contributing)

Pull requests, issues, and feedback are welcome!

---

☕ Support
---------

[](#-support)

If you find CCaptcha helpful:

👉 [Donate here](https://yaservaziri.github.io/ForutanCCaptcha/donate.html)

---

💼 Commercial License
--------------------

[](#-commercial-license)

Need this for a commercial product?

👉 [Request license](mailto:forutan.vaziri@gmail.com?subject=Commercial%20License%20Inquiry%20-%20CCaptcha)

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance66

Regular maintenance activity

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity44

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

206d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/155b5058d28cc343eaac583442b2e93186cfacea9f512900b31163cc88d0aad1?d=identicon)[yaservaziri](/maintainers/yaservaziri)

---

Top Contributors

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

### Embed Badge

![Health badge](/badges/forutan-ccaptcha/health.svg)

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

###  Alternatives

[laravel/cashier

Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

2.5k25.9M107](/packages/laravel-cashier)[laravel/pulse

Laravel Pulse is a real-time application performance monitoring tool and dashboard for your Laravel application.

1.7k12.1M99](/packages/laravel-pulse)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9682.1M97](/packages/roots-acorn)[aedart/athenaeum

Athenaeum is a mono repository; a collection of various PHP packages

245.2k](/packages/aedart-athenaeum)[scaler-tech/laravel-saml2

SAML2 Service Provider integration for Laravel applications, based on OneLogin toolkit

2737.5k](/packages/scaler-tech-laravel-saml2)

PHPackages © 2026

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