PHPackages                             oppara/cakephp-turnstile - 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. [Security](/categories/security)
4. /
5. oppara/cakephp-turnstile

ActiveCakephp-plugin[Security](/categories/security)

oppara/cakephp-turnstile
========================

CakePHP plugin for Cloudflare Turnstile.

0.1.0(3w ago)09MITPHPPHP ^8.2CI passing

Since May 17Pushed 3w agoCompare

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

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

CakePHP Turnstile
=================

[](#cakephp-turnstile)

A CakePHP plugin for working with Cloudflare Turnstile.

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

[](#requirements)

- PHP 8.2+
- CakePHP 5.x

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

[](#installation)

```
composer require oppara/cakephp-turnstile
```

Load the plugin
---------------

[](#load-the-plugin)

```
bin/cake plugin load Oppara/Turnstile
```

Configuration
-------------

[](#configuration)

Set your Turnstile keys in the environment:

```
TURNSTILE_SITE_KEY=your-site-key
TURNSTILE_SECRET_KEY=your-secret-key
```

The plugin bootstrap exposes the following defaults through `Configure::read('Turnstile')`:

```
[
    'siteKey' => getenv('TURNSTILE_SITE_KEY') ?: null,
    'secretKey' => getenv('TURNSTILE_SECRET_KEY') ?: null,
    'verifyUrl' => 'https://challenges.cloudflare.com/turnstile/v0/siteverify',
    'timeout' => 5,
    'responseFieldName' => 'cf-turnstile-response',
]
```

Usage examples
--------------

[](#usage-examples)

### Views

[](#views)

Load the helper in `src/View/AppView.php`:

```
public function initialize(): void
{
    parent::initialize();

    $this->loadHelper('Turnstile.Turnstile');
}
```

Render the script tag and widget in a template:

```
echo $this->Turnstile->script();
echo $this->Turnstile->widget([
    'theme' => 'light',
    'size' => 'flexible',
]);
```

Or render both in one call:

```
echo $this->Turnstile->render([
    'theme' => 'light',
]);
```

If your site enforces a strict Content-Security-Policy with `script-src 'nonce-…'`, pass the nonce to `script()`:

```
echo $this->Turnstile->script(['nonce' => $cspNonce]);
```

`src` is always set to the official Cloudflare URL and cannot be overridden, so any attribute you pass is added to the script tag without touching `src`.

### Controllers

[](#controllers)

Load the component in your controller:

```
public function initialize(): void
{
    parent::initialize();

    $this->loadComponent('Turnstile.Turnstile');
}
```

Read the token from the current request automatically:

```
use Oppara\Turnstile\Exception\TurnstileException;
use Psr\Log\LogLevel;

try {
    $success = $this->Turnstile->verify();
} catch (TurnstileException $e) {
    // Infrastructure / configuration error — not the user's fault.
    $this->log('Turnstile: ' . $e->getMessage(), LogLevel::ERROR);
    $this->Flash->error(__('Verification is temporarily unavailable. Please try again later.'));

    return $this->redirect(['action' => 'index']);
}

if (!$success) {
    // Cloudflare rejected the challenge — typically a user-side issue
    // (expired token, replayed token, unsolved challenge, …).
    $errors = $this->Turnstile->getResult()['error-codes'] ?? [];
    $this->log(
        sprintf('Turnstile rejected the challenge: %s', json_encode($errors)),
        LogLevel::WARNING,
    );
    $this->Flash->error(__('The challenge could not be verified. Please try again.'));

    return $this->redirect(['action' => 'index']);
}

// Verification passed — continue with the normal form handling.
```

Pass the token explicitly when needed:

```
$success = $this->Turnstile->verify(
    (string)$this->request->getData('cf-turnstile-response'),
    $this->request->clientIp(),
);
```

> **Note**
> When `verify()` is called without arguments, the component reads the token and remote IP from the current `ServerRequest`.
> The component therefore assumes a controller with an initialized `request` property (the normal Web request lifecycle).
> If you instantiate the component manually — for instance from a CLI command, queue worker, or isolated unit test — pass both arguments explicitly, or attach a `ServerRequest` to the controller first.

License
-------

[](#license)

MIT

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance95

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

 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

23d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/e4f56e30bebc27327766c3ddc1e462f0d287e5561a655d4cd140b71735c5fb7e?d=identicon)[oppara](/maintainers/oppara)

---

Top Contributors

[![oppara](https://avatars.githubusercontent.com/u/10661?v=4)](https://github.com/oppara "oppara (2 commits)")

---

Tags

plugincakephpcaptchacloudflareturnstile

###  Code Quality

TestsPHPUnit

Static AnalysisPsalm

Type Coverage Yes

### Embed Badge

![Health badge](/badges/oppara-cakephp-turnstile/health.svg)

```
[![Health](https://phpackages.com/badges/oppara-cakephp-turnstile/health.svg)](https://phpackages.com/packages/oppara-cakephp-turnstile)
```

###  Alternatives

[dereuromark/cakephp-tools

A CakePHP plugin containing lots of useful and reusable tools

336972.2k49](/packages/dereuromark-cakephp-tools)[dereuromark/cakephp-tinyauth

A CakePHP plugin to handle user authentication and authorization the easy way.

131237.3k12](/packages/dereuromark-cakephp-tinyauth)[dereuromark/cakephp-setup

A CakePHP plugin containing lots of useful management tools

35184.7k2](/packages/dereuromark-cakephp-setup)[usarise/turnstile

PHP library for Turnstile, is Cloudflare’s smart CAPTCHA alternative. It can be embedded into any website without sending traffic through Cloudflare and works without showing visitors a CAPTCHA.

24110.4k7](/packages/usarise-turnstile)[dereuromark/cakephp-translate

A CakePHP plugin for managing translations

1711.7k](/packages/dereuromark-cakephp-translate)

PHPackages © 2026

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